diff --git a/README.md b/README.md index 9ad51f8..8865144 100644 --- a/README.md +++ b/README.md @@ -19,17 +19,23 @@ with the proposed change. `cascading-pr` will wait until the CI in `actions/setup-forgejo` is updated to use what was just merged and is ready to be reviewed. -The `update` script is expected to be found in the checked out repository -running the PR. It is given three arguments: +The `update` script is expected to be found in the origin repository +running the PR. It is given four arguments: * A directory in which the destination repository is checked-out + on the base branch * A file with the JSON describing the pull request in the destination repository + * A directory in which the origin repository is checked-out + on the head branch * A file with the JSON describing the pull request in the origin repository -If changes are found in the destination repository directory, they will be -pushed as a new commit in the PR. +If changes are found in the destination repository directory after the `update` script runs, +they will be pushed as a new commit in the PR. + +When the PR is from a forked repository, the `update` script is checked out from +the default branch instead of the head branch of the fork. ## Inputs diff --git a/action.yml b/action.yml index 80766c3..789f367 100644 --- a/action.yml +++ b/action.yml @@ -18,17 +18,23 @@ description: | `actions/setup-forgejo` is updated to use what was just merged and is ready to be reviewed. - The `update` script is expected to be found in the checked out repository - running the PR. It is given three arguments: + The `update` script is expected to be found in the origin repository + running the PR. It is given four arguments: * A directory in which the destination repository is checked-out + on the base branch * A file with the JSON describing the pull request in the destination repository + * A directory in which the origin repository is checked-out + on the head branch * A file with the JSON describing the pull request in the origin repository - If changes are found in the destination repository directory, they will be - pushed as a new commit in the PR. + If changes are found in the destination repository directory after the `update` script runs, + they will be pushed as a new commit in the PR. + + When the PR is from a forked repository, the `update` script is checked out from + the default branch instead of the head branch of the fork. inputs: origin-url: diff --git a/cascading-pr.sh b/cascading-pr.sh index d3c3572..2f6ed9f 100755 --- a/cascading-pr.sh +++ b/cascading-pr.sh @@ -26,6 +26,13 @@ function repo_curl() { DOT=$TMPDIR/$repo forgejo-curl.sh "$@" } +function default_branch() { + local direction=$1 + + repo_curl ${options[${direction}_repo]} api_json ${options[${direction}_api]} > $TMPDIR/$direction.json + jq --raw-output .default_branch < $TMPDIR/$direction.json +} + function exists_branch() { local direction=$1 @@ -153,6 +160,11 @@ function pr_merged() { pr $1 | jq --raw-output .merged } +function pr_from_fork() { + pr_get $1 + pr $1 | jq --raw-output .head.repo.fork +} + function upsert_clone() { local direction=$1 ref="$2" clone=$3 @@ -206,8 +218,21 @@ function update() { upsert_clone origin "${options[origin_head]}" ${options[origin_clone]} upsert_clone destination "${options[destination_head]}" ${options[destination_clone]} ( - cd $TMPDIR/origin - ${options[update]} $TMPDIR/destination $TMPDIR/destination-pr.json $TMPDIR/origin-pr.json + local update=${options[update]} + if ! [[ "$update" =~ ^/ ]] ; then + local d + if $(pr_from_fork origin); then + local default_branch=$(default_branch origin) + log_info "PR is from a forked repository, using the default branch $default_branch to obtain the update script" + d=$TMPDIR/update + git -C $TMPDIR/origin worktree add $d $default_branch + else + d=$TMPDIR/origin + fi + update=$d/$update + fi + cd $TMPDIR + $update $TMPDIR/destination $TMPDIR/destination-pr.json $TMPDIR/origin $TMPDIR/origin-pr.json ) push destination ${options[destination_head]} ${options[destination_clone]} } diff --git a/tests/originrepo-close-merge/upgraded b/tests/originrepo-close-merge/upgraded index f53c79f..94bb293 100755 --- a/tests/originrepo-close-merge/upgraded +++ b/tests/originrepo-close-merge/upgraded @@ -4,9 +4,11 @@ set -ex destination_checkout="$1" destination_pr_json="$2" -origin_pr_json="$3" +origin_checkout="$3" +origin_pr_json="$4" test -d $destination_checkout +test -d $origin_checkout test -f $origin_pr_json date +%s > $destination_checkout/last diff --git a/tests/originrepo/upgraded b/tests/originrepo/upgraded index f53c79f..94bb293 100755 --- a/tests/originrepo/upgraded +++ b/tests/originrepo/upgraded @@ -4,9 +4,11 @@ set -ex destination_checkout="$1" destination_pr_json="$2" -origin_pr_json="$3" +origin_checkout="$3" +origin_pr_json="$4" test -d $destination_checkout +test -d $origin_checkout test -f $origin_pr_json date +%s > $destination_checkout/last diff --git a/tests/run.sh b/tests/run.sh index 3dbc299..59cabd7 100755 --- a/tests/run.sh +++ b/tests/run.sh @@ -77,7 +77,7 @@ function has_cascade_pull_request() { } function create_branch1() { - local owner=$1 repo=$2 + local owner=$1 repo=$2 modify=$3 forgejo-curl.sh api_json -X DELETE ${options[url]}/api/v1/repos/$owner/${repo}/branches/branch1 >& /dev/null || true forgejo-curl.sh api_json --data '{"new_branch_name":"branch1"}' ${options[url]}/api/v1/repos/$owner/${repo}/branches @@ -87,6 +87,7 @@ function create_branch1() { git clone -b branch1 http://user1:admin1234@${options[host_port]}/$owner/${repo} cd ${repo} echo CONTENT > README + $modify git config user.email root@example.com git config user.name username git add . @@ -96,15 +97,18 @@ function create_branch1() { ) } +function delete_pull_requests() { + local owner=$1 repo=$2 + + forgejo-curl.sh api_json ${options[url]}/api/v1/repos/$owner/${repo}/pulls | jq --raw-output '.[] | .number' | while read pr ; do + forgejo-curl.sh api_json -X DELETE ${options[url]}/api/v1/repos/$owner/${repo}/issues/$pr + done +} + + function create_pull_request() { local baseowner=$1 headowner=$2 repo=$3 - forgejo-curl.sh api_json ${options[url]}/api/v1/repos/$baseowner/${repo}/pulls | jq --raw-output '.[] | .number' | while read pr ; do - forgejo-curl.sh api_json -X DELETE ${options[url]}/api/v1/repos/$baseowner/${repo}/issues/$pr - done - - create_branch1 $headowner $repo - local head if test $baseowner == $headowner; then head=branch1 @@ -117,6 +121,14 @@ EOF forgejo-curl.sh api_json --data @$TMPDIR/data ${options[url]}/api/v1/repos/$baseowner/${repo}/pulls } +function create_pull_request_case1() { + local baseowner=$1 headowner=$2 repo=$3 + + delete_pull_requests $baseowner $repo + create_branch1 $headowner $repo + create_pull_request $baseowner $headowner $repo +} + function finalize_options() { if test -f forgejo-ip; then : ${options[host_port]:=$(cat forgejo-ip):3000} @@ -198,7 +210,7 @@ function fixture() { function no_change_no_cascade_pr() { fixture originrepo-do-nothing destinationrepo - create_pull_request user1 user1 originrepo-do-nothing + create_pull_request_case1 user1 user1 originrepo-do-nothing wait_success ${options[url]}/api/v1/repos/user1/originrepo-do-nothing $(cat $TMPDIR/user1-originrepo-do-nothing.sha) ! has_cascade_pull_request } @@ -206,17 +218,28 @@ function no_change_no_cascade_pr() { function create_and_close() { fixture originrepo destinationrepo - create_pull_request user1 user1 originrepo + create_pull_request_case1 user1 user1 originrepo wait_success ${options[url]}/api/v1/repos/user1/originrepo $(cat $TMPDIR/user1-originrepo.sha) has_cascade_pull_request close_pull_request wait_success ${options[url]}/api/v1/repos/user1/originrepo $(cat $TMPDIR/user1-originrepo.sha) } +function taint_update() { + if ! test -f upgraded ; then + echo upgraded file not found + return 1 + fi + echo 'TAINTED' > upgraded +} + function create_from_fork_and_close() { fixture originrepo destinationrepo + delete_pull_requests user1 originrepo + create_branch1 fork-org originrepo taint_update create_pull_request user1 fork-org originrepo + wait_success ${options[url]}/api/v1/repos/user1/originrepo $(cat $TMPDIR/fork-org-originrepo.sha) has_cascade_pull_request close_pull_request @@ -226,7 +249,7 @@ function create_from_fork_and_close() { function create_and_merge() { fixture originrepo destinationrepo - create_pull_request user1 user1 originrepo + create_pull_request_case1 user1 user1 originrepo wait_success ${options[url]}/api/v1/repos/user1/originrepo $(cat $TMPDIR/user1-originrepo.sha) has_cascade_pull_request merge_pull_request originrepo @@ -237,7 +260,7 @@ function create_and_merge() { function create_and_merge_close() { fixture originrepo-close-merge destinationrepo - create_pull_request user1 user1 originrepo-close-merge + create_pull_request_case1 user1 user1 originrepo-close-merge wait_success ${options[url]}/api/v1/repos/user1/originrepo-close-merge $(cat $TMPDIR/user1-originrepo-close-merge.sha) has_cascade_pull_request merge_pull_request originrepo-close-merge