diff --git a/actions/actions.sh b/actions/actions.sh index 04629063..ceb8c04c 100755 --- a/actions/actions.sh +++ b/actions/actions.sh @@ -143,7 +143,7 @@ function test_actions() { done fi - for example in echo matrix needs workflow-call lxc config-options cache checkout service container expression local-action docker-action if if-fail push tag push-cancel artifacts pull-request context; do + for example in echo matrix needs workflow-call lxc config-options cache cache-pull-request checkout service container expression local-action docker-action if if-fail push tag push-cancel artifacts pull-request context; do run actions_verify_example $example done diff --git a/actions/example-cache-pull-request/.forgejo/workflows/test.yml b/actions/example-cache-pull-request/.forgejo/workflows/test.yml new file mode 100644 index 00000000..9c4e7230 --- /dev/null +++ b/actions/example-cache-pull-request/.forgejo/workflows/test.yml @@ -0,0 +1,94 @@ +on: + pull_request: + types: + - opened + - closed + +jobs: + save-cache: + runs-on: docker + container: + image: code.forgejo.org/oci/node:20-bookworm + steps: + - name: cache restore + id: cachestep1 + uses: https://data.forgejo.org/actions/cache/restore@v4 + with: + path: | + /usr/local/bin/something + key: cachekey-${{ forge.event.pull_request.head.repo.full_name }} + + - name: cache hit + run: | + set -x + test "${{ steps.cachestep1.outputs.cache-hit }}" != true + + - name: create something + run: echo SOMETHING > /usr/local/bin/something + + - name: cache save + uses: https://data.forgejo.org/actions/cache/save@v4 + with: + path: | + /usr/local/bin/something + key: ${{ steps.cachestep1.outputs.cache-primary-key }} + + restore-cache: + runs-on: docker + needs: [save-cache] + container: + image: code.forgejo.org/oci/node:20-bookworm + steps: + - name: cache restore + id: cachestep2 + uses: https://data.forgejo.org/actions/cache/restore@v4 + with: + path: | + /usr/local/bin/something + key: cachekey-${{ forge.event.pull_request.head.repo.full_name }} + + - name: verify something + run: | + set -x + test SOMETHING = $(cat /usr/local/bin/something) + + - name: cache hit + run: | + set -x + test "${{ steps.cachestep2.outputs.cache-hit }}" = true + + test: + runs-on: docker + needs: [restore-cache] + container: + image: code.forgejo.org/oci/node:20-bookworm + options: "--volume /srv/example:/srv/example" + + steps: + - name: setup + shell: bash + run: | + set -x + test $FORGEJO_TOKEN = ${{ env.FORGEJO_TOKEN }} + test $FORGEJO_TOKEN = ${{ forge.token }} + export DEBIAN_FRONTEND=noninteractive ; apt-get -qq update ; apt-get install -y -qq curl git >& /dev/null + curl -sS -o /usr/local/bin/forgejo-curl.sh https://code.forgejo.org/forgejo/forgejo-curl/raw/branch/main/forgejo-curl.sh && chmod +x /usr/local/bin/forgejo-curl.sh + forgejo-curl.sh --token "$FORGEJO_TOKEN" login $FORGEJO_SERVER_URL + forgejo-curl.sh api_json $FORGEJO_SERVER_URL/api/v1/user + + - name: determine if the PR is from a fork + id: forked + run: | + if test ${{ forge.event.pull_request.base.repo.full_name }} = ${{ forge.event.pull_request.head.repo.full_name }} ; then + echo value=false >> $FORGEJO_OUTPUT + else + echo value=true >> $FORGEJO_OUTPUT + fi + + - name: save event + run: | + d=/srv/example/cache-pull-request/contexts/${{ forgejo.event.pull_request.head.repo.owner.username }}/$FORGEJO_EVENT_NAME + mkdir -p $d + cat > $d/forgejo-${{ forgejo.event.action }} <<'EOF' + ${{ toJSON(forgejo) }} + EOF diff --git a/actions/example-cache-pull-request/assert-contexts-closed.sh b/actions/example-cache-pull-request/assert-contexts-closed.sh new file mode 100755 index 00000000..4c0f8e27 --- /dev/null +++ b/actions/example-cache-pull-request/assert-contexts-closed.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -ex + +c=$d/contexts + +for user in cache-fork-org root; do + test -f $c/$user/pull_request/forgejo-closed +done diff --git a/actions/example-cache-pull-request/assert-contexts-opened.sh b/actions/example-cache-pull-request/assert-contexts-opened.sh new file mode 100755 index 00000000..73fcccda --- /dev/null +++ b/actions/example-cache-pull-request/assert-contexts-opened.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -ex + +c=$d/contexts + +for user in cache-fork-org root; do + test -f $c/$user/pull_request/forgejo-opened +done diff --git a/actions/example-cache-pull-request/run.sh b/actions/example-cache-pull-request/run.sh new file mode 100755 index 00000000..544b652a --- /dev/null +++ b/actions/example-cache-pull-request/run.sh @@ -0,0 +1,78 @@ +TMPDIR=$(mktemp -d) + +trap "rm -fr $TMPDIR" EXIT + +api=$url/api/v1 +export d=/srv/example/cache-pull-request + +function main() { + mkdir -p $d + + # + # open a pull request + # - from the same repository + # - from a forked repository + # + forgejo-test-helper.sh push_workflow actions/example-$example $url root example-$example setup-forgejo $token + + forgejo-curl.sh api_json --data-raw '{"username":"cache-fork-org"}' $api/orgs + forgejo-curl.sh api_json --data-raw '{"organization":"cache-fork-org"}' $api/repos/root/example-cache-pull-request/forks + + ( + cd $d + git clone $url/cache-fork-org/example-cache-pull-request fork + cd fork + git config user.email root@example.com + git config user.name username + touch file-unique-to-the-pr-branch + git add . + git commit -m 'fork change' + git push + ) + + forgejo.sh retry forgejo-curl.sh api_json --data-raw '{"title":"PR from fork","base":"main","head":"cache-fork-org:main"}' $api/repos/root/example-cache-pull-request/pulls + + ( + cd $d + git clone $url/root/example-cache-pull-request + cd example-cache-pull-request + git checkout -b other + git config user.email root@example.com + git config user.name username + touch file-unique-to-the-forked-pr + git add . + git commit -m 'other change' + git push --force -u origin other + ) + + forgejo.sh retry forgejo-curl.sh api_json --data-raw '{"title":"PR same repo","base":"main","head":"other"}' $api/repos/root/example-cache-pull-request/pulls + + export RETRY_DELAYS="10 20 60 60 60 60 60" + + # + # wait for the opened event to succeed using the cache on all pull requests + # + if ! forgejo.sh retry $EXAMPLE_DIR/assert-contexts-opened.sh; then + find $d + sed -e 's/^/[RUNNER LOGS]/' <$FORGEJO_RUNNER_LOGS + return 1 + fi + + # + # merge all pull requests + # + forgejo-curl.sh api_json $api/repos/root/example-cache-pull-request/pulls | jq -r '.[] | .number' | while read pr; do + forgejo-curl.sh api_json --data-raw '{"Do":"merge"}' $api/repos/root/example-cache-pull-request/pulls/$pr/merge + done + + # + # wait for the closed event to succeed using the cache on all pull requests + # + if ! forgejo.sh retry $EXAMPLE_DIR/assert-contexts-closed.sh; then + find $d + sed -e 's/^/[RUNNER LOGS]/' <$FORGEJO_RUNNER_LOGS + return 1 + fi +} + +main diff --git a/actions/example-cache-pull-request/runner-config.yaml b/actions/example-cache-pull-request/runner-config.yaml new file mode 100644 index 00000000..11818cc5 --- /dev/null +++ b/actions/example-cache-pull-request/runner-config.yaml @@ -0,0 +1,30 @@ + +log: + level: debug + +runner: + file: .runner + capacity: 1 + env_file: .env + timeout: 3h + insecure: false + fetch_timeout: 5s + fetch_interval: 2s + labels: ["docker:docker://code.forgejo.org/oci/node:20-bookworm"] + +cache: + enabled: true + dir: "/srv/example/cache" + host: "" + port: 0 + +container: + network: "bridge" + privileged: false + options: + workdir_parent: + valid_volumes: ["/srv/example"] + docker_host: "" + +host: + workdir_parent: diff --git a/actions/example-cache-pull-request/setup.sh b/actions/example-cache-pull-request/setup.sh new file mode 100755 index 00000000..0fb6d859 --- /dev/null +++ b/actions/example-cache-pull-request/setup.sh @@ -0,0 +1,2 @@ +mkdir -p /srv/example/cache-pull-request +FORGEJO_RUNNER_CONFIG=$EXAMPLE_DIR/runner-config.yaml forgejo-runner.sh reload diff --git a/actions/example-cache-pull-request/teardown.sh b/actions/example-cache-pull-request/teardown.sh new file mode 100755 index 00000000..b410c513 --- /dev/null +++ b/actions/example-cache-pull-request/teardown.sh @@ -0,0 +1 @@ +forgejo-runner.sh reload