From 7b5b59d8218d0af95ac20d074351e2615215064d Mon Sep 17 00:00:00 2001 From: Earl Warren Date: Sat, 7 Oct 2023 23:27:24 +0200 Subject: [PATCH 1/5] do not rely on a hacky way to obtain the sha of the branch --- .forgejo/workflows/integration.yml | 7 ++++--- README.md | 3 +-- action.yml | 3 +-- forgejo-test-helper.sh | 10 +++++++++- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/.forgejo/workflows/integration.yml b/.forgejo/workflows/integration.yml index 05bf9fa..d8ee5e1 100644 --- a/.forgejo/workflows/integration.yml +++ b/.forgejo/workflows/integration.yml @@ -31,10 +31,11 @@ jobs: # forgejo-runner.sh setup export FORGEJO_RUNNER_LOGS=forgejo-runner.log + url=http://root:admin1234@$(cat forgejo-ip):3000 + token=$(cat forgejo-token) echo "============================ demo ===================" - ./forgejo-test-helper.sh run_workflow testdata/demo http://root:admin1234@$(cat forgejo-ip):3000 root demo setup-forgejo $(cat forgejo-token) > /tmp/output - grep '^sha=' /tmp/output + forgejo-test-helper.sh run_workflow testdata/demo $url root demo setup-forgejo $token function run() { local example=$1 @@ -51,7 +52,7 @@ jobs: echo "============================ RUN example-$example ===================" bash -ex $EXAMPLE_DIR/run.sh || return 1 else - forgejo-test-helper.sh run_workflow testdata/example-$example http://root:admin1234@$(cat forgejo-ip):3000 root example-$example setup-forgejo $(cat forgejo-token) || return 1 + forgejo-test-helper.sh run_workflow testdata/example-$example $url root example-$example setup-forgejo $token || return 1 fi if test -f $EXAMPLE_DIR/teardown.sh ; then diff --git a/README.md b/README.md index 2b18601..f430992 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,7 @@ The forgejo-test-helper.sh script is available to help test and debug actions. `testrepo/.forgejo/workflows/*.yml` are replaced with `$forgejo/root/myaction`. * `forgejo-test-helper.sh push testrepo $forgejo root testrepo` Creates the repository `$forgejo/root/testrepo` and populates it with the - content of the `testrepo` directory. The SHA of the tip of the repository - is in the output, on a line starting with `sha=`. + content of the `testrepo` directory. * `forgejo-test-helper.sh build_runner $forgejo/forgejo/runner v3.0.1` Builds the forgejo runner from source in `./forgejo-runner/forgejo-runner`. `export PATH=$(pwd)/forgejo-runner:$PATH` will ensure that calling `forgejo-runner.sh` diff --git a/action.yml b/action.yml index 086d9e9..a9bc3f4 100644 --- a/action.yml +++ b/action.yml @@ -19,8 +19,7 @@ description: | `testrepo/.forgejo/workflows/*.yml` are replaced with `$forgejo/root/myaction`. * `forgejo-test-helper.sh push testrepo $forgejo root testrepo` Creates the repository `$forgejo/root/testrepo` and populates it with the - content of the `testrepo` directory. The SHA of the tip of the repository - is in the output, on a line starting with `sha=`. + content of the `testrepo` directory. * `forgejo-test-helper.sh build_runner $forgejo/forgejo/runner v3.0.1` Builds the forgejo runner from source in `./forgejo-runner/forgejo-runner`. `export PATH=$(pwd)/forgejo-runner:$PATH` will ensure that calling `forgejo-runner.sh` diff --git a/forgejo-test-helper.sh b/forgejo-test-helper.sh index 01dae72..39ccca9 100755 --- a/forgejo-test-helper.sh +++ b/forgejo-test-helper.sh @@ -44,6 +44,15 @@ function build_runner() { forgejo-runner --version } +function branch_tip() { + local url="$1" + local repo="$2" + local branch="$3" + + forgejo.sh retry forgejo-curl.sh api_json $url/api/v1/repos/$repo/branches/$branch >& /dev/null + forgejo-curl.sh api_json $url/api/v1/repos/$repo/branches/$branch | jq --raw-output .commit.id +} + function get_status() { local url="$1" local repo="$2" @@ -111,7 +120,6 @@ function push() { git push --force -u origin main sha=$(git rev-parse HEAD) echo $sha > SHA - echo sha=$sha ) } From 0fc67c08f74f3fa2c5b43b4025e03d98f320e868 Mon Sep 17 00:00:00 2001 From: Earl Warren Date: Sat, 7 Oct 2023 21:59:39 +0200 Subject: [PATCH 2/5] example-checkout: only one workflow to avoid breakage aggregated statuses are confusing --- .../.forgejo/workflows/{v3.yml => test.yml} | 8 +++++--- testdata/example-checkout/.forgejo/workflows/v4.yml | 8 -------- 2 files changed, 5 insertions(+), 11 deletions(-) rename testdata/example-checkout/.forgejo/workflows/{v3.yml => test.yml} (51%) delete mode 100644 testdata/example-checkout/.forgejo/workflows/v4.yml diff --git a/testdata/example-checkout/.forgejo/workflows/v3.yml b/testdata/example-checkout/.forgejo/workflows/test.yml similarity index 51% rename from testdata/example-checkout/.forgejo/workflows/v3.yml rename to testdata/example-checkout/.forgejo/workflows/test.yml index 33533a6..7b88160 100644 --- a/testdata/example-checkout/.forgejo/workflows/v3.yml +++ b/testdata/example-checkout/.forgejo/workflows/test.yml @@ -1,8 +1,10 @@ on: [push] jobs: - ls: + v3: runs-on: docker steps: - uses: actions/checkout@v3 - - run: | - ls ${{ github.workspace }} + v4: + runs-on: docker + steps: + - uses: actions/checkout@v4 diff --git a/testdata/example-checkout/.forgejo/workflows/v4.yml b/testdata/example-checkout/.forgejo/workflows/v4.yml deleted file mode 100644 index 34c9b57..0000000 --- a/testdata/example-checkout/.forgejo/workflows/v4.yml +++ /dev/null @@ -1,8 +0,0 @@ -on: [push] -jobs: - ls: - runs-on: docker - steps: - - uses: actions/checkout@v4 - - run: | - ls ${{ github.workspace }} From 44400632c5afd34cad53992c8721e93f86eb0d4b Mon Sep 17 00:00:00 2001 From: Earl Warren Date: Sat, 7 Oct 2023 22:07:36 +0200 Subject: [PATCH 3/5] document variable controlled debug loop --- .forgejo/workflows/integration.yml | 4 ++-- README.md | 19 +++++++++++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/.forgejo/workflows/integration.yml b/.forgejo/workflows/integration.yml index d8ee5e1..9a5940f 100644 --- a/.forgejo/workflows/integration.yml +++ b/.forgejo/workflows/integration.yml @@ -9,10 +9,10 @@ jobs: - version: "1.21.0-2-rc0" image: codeberg.org/forgejo-experimental/forgejo # keep "cron" last otherwise it will linger and pollute the following runs - tests: "${{ vars.V121_TESTS || 'echo artifacts service checkout pull-request container expression local-action docker-action if if-fail cron' }}" + tests: "${{ vars.V1_21_TESTS || 'echo push-cancel artifacts service checkout pull-request container expression local-action docker-action if if-fail cron' }}" - version: "1.20" image: codeberg.org/forgejo/forgejo - tests: "${{ vars.V120_TESTS || 'echo checkout service container expression local-action docker-action if if-fail' }}" + tests: "${{ vars.V1_20_TESTS || 'echo checkout service container expression local-action docker-action if if-fail' }}" steps: - uses: actions/checkout@v3 - if: matrix.info.tests != 'none' diff --git a/README.md b/README.md index f430992..fc87acf 100644 --- a/README.md +++ b/README.md @@ -86,9 +86,13 @@ jobs: ## Hacking -* Update the README from the action file with https://github.com/npalm/action-docs `action-docs --update-readme` +### Documentation -To manually run and debug workflows from `testdata/example-*`, from +Update the README from the action file with https://github.com/npalm/action-docs `action-docs --update-readme` + +### Local testing + +To run and debug workflows from `testdata/example-*`, from the root of the source directory, with docker and forgejo-curl.sh installed, mimic what `.forgejo/workflows/integration.yml` does. There may be some manual tweaking (such as creating temporary directories) @@ -105,3 +109,14 @@ because the tests run as root, but they do not need to run as root. * `forgejo-test-helper.sh run_workflow testdata/example-$example http://root:admin1234@$(cat forgejo-ip):3000 root example-$example setup-forgejo $(cat forgejo-token)` * `forgejo-runner.sh teardown` * `forgejo.sh teardown` + +### Remote testing + +To reduce the runtime the following variables can be set to control +the number of cases run by the +[integration](.forgejo/workflows/integration.yml) tests. If set to +**none** they are not run at all for that version of Forgejo. If +it does not exist, all tests are run. + +* `V1_21_TESTS` +* `V1_20_TESTS` From fccbd1ce6bf431919b61ab3f8bc713ae29685da0 Mon Sep 17 00:00:00 2001 From: Earl Warren Date: Sat, 7 Oct 2023 21:38:23 +0200 Subject: [PATCH 4/5] example-push-cancel: test that pushing to a branch cancels workflows --- forgejo-test-helper.sh | 43 ++++++++++++++----- .../.forgejo/workflows/test.yml | 6 +++ testdata/example-push-cancel/run.sh | 20 +++++++++ testdata/example-push-cancel/teardown.sh | 4 ++ 4 files changed, 63 insertions(+), 10 deletions(-) create mode 100644 testdata/example-push-cancel/.forgejo/workflows/test.yml create mode 100755 testdata/example-push-cancel/run.sh create mode 100644 testdata/example-push-cancel/teardown.sh diff --git a/forgejo-test-helper.sh b/forgejo-test-helper.sh index 39ccca9..a6bec88 100755 --- a/forgejo-test-helper.sh +++ b/forgejo-test-helper.sh @@ -5,8 +5,8 @@ set -ex export DEBIAN_FRONTEND=noninteractive -: ${LOOPS:=40} -: ${LOOP_DELAY:=10} +: ${LOOPS:=80} +: ${LOOP_DELAY:=5} DIR=$(mktemp -d) trap "rm -fr $DIR" EXIT @@ -65,25 +65,48 @@ function check_status() { local url="$1" local repo="$2" local sha="$3" + local expected_status="$4" + local expected_description="$5" - local state=$(get_status $url $repo $sha | jq --raw-output .state) - echo $state - test "$state" != "" -a "$state" != "pending" -a "$state" != "running" -a "$state" != "null" + get_status $url $repo $sha > /tmp/status.json + local status="$(jq --raw-output .state < /tmp/status.json)" + local description="$(jq --raw-output .statuses[0].description < /tmp/status.json)" + if test "$status" = "$expected_status" && test -z "$expected_description" -o "$description" = "$expected_description"; then + echo OK + elif test "$status" = "failure" -o "$status" = "success"; then + echo NOK + else + echo RETRY + fi } function wait_success() { - local url="$1" - local repo="$2" - local sha="$3" + wait_status success "$@" +} + +function wait_failure() { + wait_status failure "$@" +} + +function wait_running() { + wait_status pending "$@" "Has started running" +} + +function wait_status() { + local status="$1" + local url="$2" + local repo="$3" + local sha="$4" + local description="$5" for i in $(seq $LOOPS); do - if check_status "$url" "$repo" "$sha"; then + if test $(check_status "$url" "$repo" "$sha" "$status" "$description") != RETRY ; then break fi test "$FORGEJO_RUNNER_LOGS" && tail $FORGEJO_RUNNER_LOGS sleep $LOOP_DELAY done - if ! test "$(check_status "$url" "$repo" "$sha")" = "success" ; then + if test $(check_status "$url" "$repo" "$sha" "$status" "$description") != "OK" ; then get_status $url $repo $sha | jq .statuses test "$FORGEJO_RUNNER_LOGS" && cat $FORGEJO_RUNNER_LOGS return 1 diff --git a/testdata/example-push-cancel/.forgejo/workflows/test.yml b/testdata/example-push-cancel/.forgejo/workflows/test.yml new file mode 100644 index 0000000..556f5e8 --- /dev/null +++ b/testdata/example-push-cancel/.forgejo/workflows/test.yml @@ -0,0 +1,6 @@ +on: [push] +jobs: + test: + runs-on: docker + steps: + - run: sleep infinity diff --git a/testdata/example-push-cancel/run.sh b/testdata/example-push-cancel/run.sh new file mode 100755 index 0000000..aeb6c66 --- /dev/null +++ b/testdata/example-push-cancel/run.sh @@ -0,0 +1,20 @@ +url=http://root:admin1234@$(cat forgejo-ip):3000 +token=$(cat forgejo-token) +repo=root/example-$example +# +# push the repository +# +forgejo-test-helper.sh push_workflow testdata/example-$example $url root example-$example setup-forgejo $token +sha=$(forgejo-test-helper.sh branch_tip $url $repo main) +# +# wait for the workflow (sleep infinity) to start running +# +forgejo-test-helper.sh wait_running $url $repo $sha +# +# push to the same branch +# +forgejo-test-helper.sh push_workflow testdata/example-$example $url root example-$example setup-forgejo $token +# +# wait for the workflow to be canceld as a result of the previous push +# +forgejo-test-helper.sh wait_failure $url $repo $sha 'Has been cancelled' diff --git a/testdata/example-push-cancel/teardown.sh b/testdata/example-push-cancel/teardown.sh new file mode 100644 index 0000000..ae9987a --- /dev/null +++ b/testdata/example-push-cancel/teardown.sh @@ -0,0 +1,4 @@ +# +# this will effectively discard any linger workflow so they do not interfere with other tests +# +forgejo-runner.sh reload From 7243566bcefce9c3d25a349f57b2e0df910dfd1e Mon Sep 17 00:00:00 2001 From: Earl Warren Date: Sat, 7 Oct 2023 23:51:05 +0200 Subject: [PATCH 5/5] example-service: only one workflow to avoid breakage --- .../.forgejo/workflows/postgresql.yml | 19 ----------------- .../workflows/{volume.yml => test.yml} | 21 +++++++++++++++++++ 2 files changed, 21 insertions(+), 19 deletions(-) delete mode 100644 testdata/example-service/.forgejo/workflows/postgresql.yml rename testdata/example-service/.forgejo/workflows/{volume.yml => test.yml} (71%) diff --git a/testdata/example-service/.forgejo/workflows/postgresql.yml b/testdata/example-service/.forgejo/workflows/postgresql.yml deleted file mode 100644 index 9d9d30e..0000000 --- a/testdata/example-service/.forgejo/workflows/postgresql.yml +++ /dev/null @@ -1,19 +0,0 @@ -on: [push] - -jobs: - test: - runs-on: docker - container: - image: code.forgejo.org/oci/debian:bookworm - - services: - pgsql: - image: code.forgejo.org/oci/postgres:15 - env: - POSTGRES_DB: test - POSTGRES_PASSWORD: postgres - steps: - - run: | - apt-get update -qq - apt-get install -y -qq postgresql-client - PGPASSWORD=postgres psql -h pgsql -U postgres -c '\dt' test diff --git a/testdata/example-service/.forgejo/workflows/volume.yml b/testdata/example-service/.forgejo/workflows/test.yml similarity index 71% rename from testdata/example-service/.forgejo/workflows/volume.yml rename to testdata/example-service/.forgejo/workflows/test.yml index 0649f50..438203c 100644 --- a/testdata/example-service/.forgejo/workflows/volume.yml +++ b/testdata/example-service/.forgejo/workflows/test.yml @@ -2,9 +2,29 @@ on: [push] jobs: # + # No volume involved + # + simple: + runs-on: docker + container: + image: code.forgejo.org/oci/debian:bookworm + + services: + pgsql: + image: code.forgejo.org/oci/postgres:15 + env: + POSTGRES_DB: test + POSTGRES_PASSWORD: postgres + steps: + - run: | + apt-get update -qq + apt-get install -y -qq postgresql-client + PGPASSWORD=postgres psql -h pgsql -U postgres -c '\dt' test + # # A --volume option will expose the volume from the docker host to the job # volume-on-step: + needs: [simple] runs-on: docker container: image: code.forgejo.org/oci/debian:bookworm @@ -19,6 +39,7 @@ jobs: # A --volume option will expose the volume from the docker host to the service # volume-on-service: + needs: [volume-on-step] runs-on: docker container: image: code.forgejo.org/oci/debian:bookworm