Merge pull request 'actions: add automerge example' (#187) from earl-warren/end-to-end:wip-automerge into main
Reviewed-on: https://code.forgejo.org/forgejo/end-to-end/pulls/187 Reviewed-by: thefox <thefox@noreply.code.forgejo.org>
This commit is contained in:
commit
7fd268b02f
7 changed files with 202 additions and 2 deletions
|
@ -1,3 +1,10 @@
|
||||||
root = true
|
root = true
|
||||||
|
|
||||||
[*]
|
[*]
|
||||||
tab_width: 8
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
tab_width = 4
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
|
|
@ -114,7 +114,7 @@ function test_actions() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if dpkg --compare-versions $version ge 7.1 ; then
|
if dpkg --compare-versions $version ge 7.1 ; then
|
||||||
for example in post-7-0-schedule ; do
|
for example in automerge post-7-0-schedule ; do
|
||||||
run actions_verify_example $example
|
run actions_verify_example $example
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
13
actions/example-automerge/.forgejo/workflows/test.yml
Normal file
13
actions/example-automerge/.forgejo/workflows/test.yml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: code.forgejo.org/oci/node:20-bookworm
|
||||||
|
options: "--volume /srv/example:/srv/example"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- run: |
|
||||||
|
${{ vars.SCRIPT }}
|
69
actions/example-automerge/run.sh
Executable file
69
actions/example-automerge/run.sh
Executable file
|
@ -0,0 +1,69 @@
|
||||||
|
TMPDIR=$(mktemp -d)
|
||||||
|
|
||||||
|
trap "rm -fr $TMPDIR" EXIT
|
||||||
|
|
||||||
|
source $EXAMPLE_DIR/../../lib/lib.sh
|
||||||
|
|
||||||
|
api=$url/api/v1
|
||||||
|
export d=/srv/example/automerge
|
||||||
|
|
||||||
|
PROOF='some proof'
|
||||||
|
|
||||||
|
function main() {
|
||||||
|
#
|
||||||
|
# repository with a pull_request event workflow that always succeeds
|
||||||
|
#
|
||||||
|
mkdir -p $d
|
||||||
|
|
||||||
|
forgejo-test-helper.sh push_workflow actions/example-$example $url root example-$example setup-forgejo $token
|
||||||
|
|
||||||
|
local repo=root/example-automerge
|
||||||
|
|
||||||
|
forgejo-curl.sh api_json -X DELETE $api/repos/$repo/actions/variables/SCRIPT >&/dev/null || true
|
||||||
|
forgejo-curl.sh api_json -X POST --data-raw '{"value":"true"}' $api/repos/$repo/actions/variables/SCRIPT
|
||||||
|
|
||||||
|
(
|
||||||
|
cd $d
|
||||||
|
git clone $url/$repo
|
||||||
|
cd example-automerge
|
||||||
|
git checkout -b other
|
||||||
|
git config user.email root@example.com
|
||||||
|
git config user.name username
|
||||||
|
touch file-unique-to-the-pr-branch
|
||||||
|
echo other $PROOF >>README
|
||||||
|
git add .
|
||||||
|
git commit -m 'other change'
|
||||||
|
git push --force -u origin other
|
||||||
|
)
|
||||||
|
|
||||||
|
#
|
||||||
|
# make sure the runner won't race with the sequence that follows
|
||||||
|
#
|
||||||
|
forgejo-runner.sh teardown
|
||||||
|
#
|
||||||
|
# create a PR and schedule it for automerge when the workflow succeeds
|
||||||
|
#
|
||||||
|
api_pr_delete_all $api $repo
|
||||||
|
forgejo-curl.sh api_json --data-raw '{"title":"PR title","base":"main","head":"other"}' $api/repos/$repo/pulls >$TMPDIR/pr.json
|
||||||
|
local pr=$(jq -r .number <$TMPDIR/pr.json)
|
||||||
|
forgejo-curl.sh api_json --data-raw '{"Do":"merge","merge_when_checks_succeed":true}' $api/repos/$repo/pulls/$pr/merge
|
||||||
|
if api_pr_is_merged $api $repo $pr; then
|
||||||
|
echo pull request already merged although it should not be
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
#
|
||||||
|
# run the workflow
|
||||||
|
#
|
||||||
|
forgejo-runner.sh run
|
||||||
|
local sha=$(api_branch_tip $api $repo other)
|
||||||
|
api_pr_wait_success $api $repo $sha
|
||||||
|
#
|
||||||
|
# verify the PR was automerged
|
||||||
|
#
|
||||||
|
if ! retry api_pr_is_merged $api $repo $pr; then
|
||||||
|
echo pull request is not automerged as expected
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
main
|
1
actions/example-automerge/setup.sh
Executable file
1
actions/example-automerge/setup.sh
Executable file
|
@ -0,0 +1 @@
|
||||||
|
mkdir -p /srv/example/automerge
|
108
lib/api.sh
Normal file
108
lib/api.sh
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Copyright 2024 The Forgejo Authors
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
API_TMPDIR=$(mktemp -d)
|
||||||
|
|
||||||
|
function api_branch_tip() {
|
||||||
|
local api="$1"
|
||||||
|
local repo="$2"
|
||||||
|
local branch="$3"
|
||||||
|
|
||||||
|
retry forgejo-curl.sh api_json $api/repos/$repo/branches/$branch >&/dev/null
|
||||||
|
forgejo-curl.sh api_json $api/repos/$repo/branches/$branch | jq --raw-output .commit.id
|
||||||
|
}
|
||||||
|
|
||||||
|
function api_pr_is_merged() {
|
||||||
|
local api="$1"
|
||||||
|
local repo="$2"
|
||||||
|
local pr="$3"
|
||||||
|
|
||||||
|
forgejo-curl.sh api_json $api/repos/$repo/pulls/$pr >$API_TMPDIR/pr.json
|
||||||
|
$(jq -r .merged <$API_TMPDIR/pr.json)
|
||||||
|
}
|
||||||
|
|
||||||
|
function api_pr_delete_all() {
|
||||||
|
local api="$1"
|
||||||
|
local repo="$2"
|
||||||
|
|
||||||
|
forgejo-curl.sh api_json $api/repos/${repo}/pulls | jq --raw-output '.[] | .number' | while read pr; do
|
||||||
|
forgejo-curl.sh api_json -X DELETE $api/repos/${repo}/issues/$pr
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
function api_pr_get_status() {
|
||||||
|
local api="$1"
|
||||||
|
local repo="$2"
|
||||||
|
local sha="$3"
|
||||||
|
|
||||||
|
forgejo-curl.sh api_json $api/repos/$repo/commits/$sha/status
|
||||||
|
}
|
||||||
|
|
||||||
|
function api_pr_check_status() {
|
||||||
|
local api="$1"
|
||||||
|
local repo="$2"
|
||||||
|
local sha="$3"
|
||||||
|
local expected_status="$4"
|
||||||
|
local expected_description="$5"
|
||||||
|
|
||||||
|
api_pr_get_status $api $repo $sha >$API_TMPDIR/status.json
|
||||||
|
local status="$(jq --raw-output .state <$API_TMPDIR/status.json)"
|
||||||
|
local description="$(jq --raw-output .statuses[0].description <$API_TMPDIR/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 api_pr_wait_success() {
|
||||||
|
api_pr_wait_status success "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
function api_pr_wait_failure() {
|
||||||
|
api_pr_wait_status failure "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
function api_pr_wait_running() {
|
||||||
|
api_pr_wait_status pending "$@" "Has started running"
|
||||||
|
}
|
||||||
|
|
||||||
|
function api_pr_wait_log() {
|
||||||
|
local sha="$1" expected_status="$2" expected_description="$3"
|
||||||
|
local status="$(jq --raw-output .state <$API_TMPDIR/status.json)"
|
||||||
|
local description="$(jq --raw-output .statuses[0].description <$API_TMPDIR/status.json)"
|
||||||
|
if test "$expected_description"; then
|
||||||
|
expected_description=" '$expected_description'"
|
||||||
|
fi
|
||||||
|
log_info "$sha status waiting '$expected_status'$expected_description, currently '$status' '$description'"
|
||||||
|
}
|
||||||
|
|
||||||
|
# default loop delay is 3600 sec (1 hour)
|
||||||
|
: ${API_LOOPS:=100}
|
||||||
|
: ${API_LOOP_DELAY:=36}
|
||||||
|
|
||||||
|
function api_pr_wait_status() {
|
||||||
|
local status="$1"
|
||||||
|
local api="$2"
|
||||||
|
local repo="$3"
|
||||||
|
local sha="$4"
|
||||||
|
local description="$5"
|
||||||
|
|
||||||
|
for i in $(seq $API_LOOPS); do
|
||||||
|
if test $(api_pr_check_status "$api" "$repo" "$sha" "$status" "$description") != RETRY; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
api_pr_wait_log "$sha" "$status" "$description"
|
||||||
|
sleep $API_LOOP_DELAY
|
||||||
|
done
|
||||||
|
if test $(api_pr_check_status "$api" "$repo" "$sha" "$status" "$description") = "OK"; then
|
||||||
|
log_info "$sha status OK"
|
||||||
|
else
|
||||||
|
api_pr_get_status $api $repo $sha | jq .statuses
|
||||||
|
log_info "$sha status NOK"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
LIB_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
LIB_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
|
||||||
|
source $LIB_DIR/api.sh
|
||||||
|
|
||||||
if ${VERBOSE:-false} ; then
|
if ${VERBOSE:-false} ; then
|
||||||
set -ex
|
set -ex
|
||||||
PS4='${BASH_SOURCE[0]}:$LINENO: ${FUNCNAME[0]}: '
|
PS4='${BASH_SOURCE[0]}:$LINENO: ${FUNCNAME[0]}: '
|
||||||
|
|
Loading…
Add table
Reference in a new issue