mirror of
https://code.forgejo.org/actions/cascading-pr.git
synced 2025-04-21 08:28:44 +00:00
Merge pull request 'allow running on a ref instead of a PR' (#16) from earl-warren/cascading-pr:wip-ref into main
Reviewed-on: https://code.forgejo.org/actions/cascading-pr/pulls/16 Reviewed-by: dachary <dachary@noreply.code.forgejo.org>
This commit is contained in:
commit
3402cff299
12 changed files with 326 additions and 85 deletions
83
README.md
83
README.md
|
@ -4,58 +4,69 @@ Create and synchronize a PR in a dependent repository
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
|
|
||||||
If repository A depends on repository B, `cascadinging-pr` can be
|
If repository A depends on repository B, `cascadinging-pr` can be used
|
||||||
used by a workflow in repository B to trigger the CI on repository A
|
by a workflow in repository B to trigger the CI on repository A and
|
||||||
and verify it passes when it will upgrade with the proposed change
|
verify it passes when using a modified version of repository B. This
|
||||||
from repository B.
|
modified version could be a pull request, a branch or a reference.
|
||||||
|
|
||||||
|
In the simplest case `cascading-pr` runs a workflow in `destination-repo`
|
||||||
|
that uses `origin-ref` and blocks until it completes.
|
||||||
|
|
||||||
|
As an example, when a tag is set in Forgejo and builds a new release,
|
||||||
|
it is concluded by a call to `cascading-pr` that runs
|
||||||
|
[end-to-end](https://code.forgejo.org/forgejo/end-to-end/) tests on
|
||||||
|
the newly built release to verify it works as expected.
|
||||||
|
|
||||||
When used in a workflow triggered by a PR event in `origin-repo`,
|
When used in a workflow triggered by a PR event in `origin-repo`,
|
||||||
`cascading-pr` will create, update and close a matching PR in
|
`cascading-pr` will create, update and close a matching PR in the
|
||||||
another repository (`destination-repo`). When the PR is updated,
|
`destination-repo`. When the PR is updated, `cascading-pr` will
|
||||||
`cascading-pr` subsequently will update the matching PR. The
|
update the matching PR. It waits for the workflow triggered by these
|
||||||
worfklows in `origin-repo` will wait for the workflow in
|
updates in `destination-repo` to complete. If fails, `cascading-pr`,
|
||||||
`destination-repo` to complete. If the workflow in
|
also fails.
|
||||||
`destination-repo` fails, the workflow in `origin-repo` will also
|
|
||||||
fail.
|
|
||||||
|
|
||||||
As an example, when a PR is created in
|
As an example, when a PR is created in
|
||||||
[`forgejo/runner`](https://code.forgejo.org/forgejo/runner/), a
|
[`forgejo/runner`](https://code.forgejo.org/forgejo/runner/), a
|
||||||
matching PR is created in
|
matching PR is created in
|
||||||
[`actions/setup-forgejo`](https://code.forgejo.org/actions/setup-forgejo/)
|
[`actions/setup-forgejo`](https://code.forgejo.org/actions/setup-forgejo/)
|
||||||
with the proposed change. `cascading-pr` will wait until the CI in
|
with the proposed change and `cascading-pr` waits until the CI in
|
||||||
`actions/setup-forgejo` is successful.
|
`actions/setup-forgejo` is successful.
|
||||||
|
|
||||||
The `update` script is expected to be found in the origin repository
|
The `update` script is expected to be found in `origin-repo` and is
|
||||||
running the PR. It is given four arguments:
|
given the following arguments:
|
||||||
|
|
||||||
* A directory in which the destination repository (or a fork) is checked-out
|
* A directory path in which the `destination-branch` of `destination-repo`
|
||||||
on the base branch
|
(or a fork) is checked-out.
|
||||||
* A file with the JSON describing the pull request in the
|
* The path to a JSON file describing the pull request in `destination-repo`.
|
||||||
destination repository
|
* A directory path in which the head of `origin-repo` is checked-out at:
|
||||||
* A directory in which the origin repository is checked-out
|
* if `origin-pr` is specified, the head branch of `origin-pr`
|
||||||
on the head branch
|
* otherwise `origin-ref`
|
||||||
* A file with the JSON describing the pull request in the
|
* Information about the `origin-repo`
|
||||||
origin repository
|
* if `origin-pr` is specified, the path to a JSON file desccribing
|
||||||
|
the pull request in `origin-repo`
|
||||||
|
* otherwise `origin-ref`
|
||||||
|
|
||||||
If changes are found in the destination repository directory after the `update` script runs,
|
If changes are found in the destination repository directory after
|
||||||
they will be pushed as a new commit in the PR.
|
the `update` script runs, they will be pushed as a new commit in the
|
||||||
|
PR in the `destination-repo`.
|
||||||
|
|
||||||
`origin-token` is used when accessing `origin-repo` and needs the
|
`origin-token` is used when accessing `origin-repo` and needs the
|
||||||
`read:user`, `read:repository` and `write:issue` scopes.
|
`read:user`, `read:repository` and `write:issue` scopes.
|
||||||
|
|
||||||
`destination-token` is used to push the branch that contains an
|
`destination-token` is used to push the branch that contains an
|
||||||
update to `destination-repo` and to open a pull request. It needs
|
update to `destination-repo` (or `destination-fork-repo`) and open a
|
||||||
the `read:user`, `write:repository` and `write:issue` scopes.
|
pull request. It needs the `read:user`, `write:repository` and
|
||||||
|
`write:issue` scopes.
|
||||||
|
|
||||||
It is recommended that a dedicated user is used to create
|
It is recommended that a dedicated user is used to create
|
||||||
`destination-token` and that `destination-fork-repo` is always used
|
`destination-token` and that `destination-fork-repo` is always used
|
||||||
unless the users who are able to create pull requests are trusted.
|
unless the users who are able to create pull requests are trusted.
|
||||||
|
|
||||||
When the PR is from a forked repository, the `update` script is run
|
When the PR in the `destination-repo` is from a forked repository,
|
||||||
from the default branch of the base repository instead of the head
|
the `update` script is run from the default branch of
|
||||||
branch of the fork. The pull request author must not be trusted
|
`destination-repo` instead of the head of the PR which is a branch
|
||||||
and it is imperative that the `update` script never runs anything
|
in destination-fork-repo. The PR author must not be trusted and it
|
||||||
found in the head branch of the pull request.
|
is imperative that the `update` script never runs anything found in
|
||||||
|
the head branch of the PR.
|
||||||
|
|
||||||
If the fork of the destination repository is specified and it does
|
If the fork of the destination repository is specified and it does
|
||||||
not exist, it is created.
|
not exist, it is created.
|
||||||
|
@ -68,7 +79,8 @@ not exist, it is created.
|
||||||
| origin-url | URL of the Forgejo instance where the PR that triggers the action is located (e.g. https://code.forgejo.org) | `true` | |
|
| origin-url | URL of the Forgejo instance where the PR that triggers the action is located (e.g. https://code.forgejo.org) | `true` | |
|
||||||
| origin-repo | the repository in which the PR was created | `true` | |
|
| origin-repo | the repository in which the PR was created | `true` | |
|
||||||
| origin-token | a token with write permission on origin-repo | `true` | |
|
| origin-token | a token with write permission on origin-repo | `true` | |
|
||||||
| origin-pr | number of the PR in {orign-repo} | `true` | |
|
| origin-pr | number of the PR in {orign-repo}, mutually exclusive with {origin-ref} | `false` | |
|
||||||
|
| origin-ref | reference in {orign-repo}, mutually exclusive with {origin-pr} | `false` | |
|
||||||
| destination-url | URL of the Forgejo instance where the cascading PR is created or updated (e.g. https://code.forgejo.org) | `true` | |
|
| destination-url | URL of the Forgejo instance where the cascading PR is created or updated (e.g. https://code.forgejo.org) | `true` | |
|
||||||
| destination-repo | the repository in which the cascading PR is created or updated | `true` | |
|
| destination-repo | the repository in which the cascading PR is created or updated | `true` | |
|
||||||
| destination-fork-repo | the fork of {destination-repo} in which the {destination-branch} will be created or updated | `false` | |
|
| destination-fork-repo | the fork of {destination-repo} in which the {destination-branch} will be created or updated | `false` | |
|
||||||
|
@ -168,12 +180,13 @@ git clone https://code.forgejo.org/actions/setup-forgejo
|
||||||
export PATH=$(pwd)/setup-forgejo:$PATH
|
export PATH=$(pwd)/setup-forgejo:$PATH
|
||||||
git clone https://code.forgejo.org/actions/cascading-pr
|
git clone https://code.forgejo.org/actions/cascading-pr
|
||||||
cd cascading-pr
|
cd cascading-pr
|
||||||
|
export DIR=/tmp/forgejo-for-cascading-pr
|
||||||
forgejo-curl.sh logout
|
forgejo-curl.sh logout
|
||||||
forgejo-runner.sh teardown
|
forgejo-runner.sh teardown
|
||||||
forgejo.sh teardown
|
forgejo-binary.sh teardown
|
||||||
forgejo.sh setup root admin1234 codeberg.org/forgejo/forgejo 1.21
|
forgejo-binary.sh setup root admin1234 https://codeberg.org/forgejo/forgejo/releases/download/v1.21.3-0/forgejo-1.21.3-0-linux-amd64
|
||||||
FORGEJO_RUNNER_CONFIG=$(pwd)/tests/runner-config.yaml forgejo-runner.sh setup
|
FORGEJO_RUNNER_CONFIG=$(pwd)/tests/runner-config.yaml forgejo-runner.sh setup
|
||||||
url=http://$(cat forgejo-ip):3000
|
url=$(cat $DIR/forgejo-url)
|
||||||
firefox $url
|
firefox $url
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
79
action.yml
79
action.yml
|
@ -3,58 +3,69 @@ name: 'Cascading PR'
|
||||||
author: 'Forgejo authors'
|
author: 'Forgejo authors'
|
||||||
description: |
|
description: |
|
||||||
|
|
||||||
If repository A depends on repository B, `cascadinging-pr` can be
|
If repository A depends on repository B, `cascadinging-pr` can be used
|
||||||
used by a workflow in repository B to trigger the CI on repository A
|
by a workflow in repository B to trigger the CI on repository A and
|
||||||
and verify it passes when it will upgrade with the proposed change
|
verify it passes when using a modified version of repository B. This
|
||||||
from repository B.
|
modified version could be a pull request, a branch or a reference.
|
||||||
|
|
||||||
|
In the simplest case `cascading-pr` runs a workflow in `destination-repo`
|
||||||
|
that uses `origin-ref` and blocks until it completes.
|
||||||
|
|
||||||
|
As an example, when a tag is set in Forgejo and builds a new release,
|
||||||
|
it is concluded by a call to `cascading-pr` that runs
|
||||||
|
[end-to-end](https://code.forgejo.org/forgejo/end-to-end/) tests on
|
||||||
|
the newly built release to verify it works as expected.
|
||||||
|
|
||||||
When used in a workflow triggered by a PR event in `origin-repo`,
|
When used in a workflow triggered by a PR event in `origin-repo`,
|
||||||
`cascading-pr` will create, update and close a matching PR in
|
`cascading-pr` will create, update and close a matching PR in the
|
||||||
another repository (`destination-repo`). When the PR is updated,
|
`destination-repo`. When the PR is updated, `cascading-pr` will
|
||||||
`cascading-pr` subsequently will update the matching PR. The
|
update the matching PR. It waits for the workflow triggered by these
|
||||||
worfklows in `origin-repo` will wait for the workflow in
|
updates in `destination-repo` to complete. If fails, `cascading-pr`,
|
||||||
`destination-repo` to complete. If the workflow in
|
also fails.
|
||||||
`destination-repo` fails, the workflow in `origin-repo` will also
|
|
||||||
fail.
|
|
||||||
|
|
||||||
As an example, when a PR is created in
|
As an example, when a PR is created in
|
||||||
[`forgejo/runner`](https://code.forgejo.org/forgejo/runner/), a
|
[`forgejo/runner`](https://code.forgejo.org/forgejo/runner/), a
|
||||||
matching PR is created in
|
matching PR is created in
|
||||||
[`actions/setup-forgejo`](https://code.forgejo.org/actions/setup-forgejo/)
|
[`actions/setup-forgejo`](https://code.forgejo.org/actions/setup-forgejo/)
|
||||||
with the proposed change. `cascading-pr` will wait until the CI in
|
with the proposed change and `cascading-pr` waits until the CI in
|
||||||
`actions/setup-forgejo` is successful.
|
`actions/setup-forgejo` is successful.
|
||||||
|
|
||||||
The `update` script is expected to be found in the origin repository
|
The `update` script is expected to be found in `origin-repo` and is
|
||||||
running the PR. It is given four arguments:
|
given the following arguments:
|
||||||
|
|
||||||
* A directory in which the destination repository (or a fork) is checked-out
|
* A directory path in which the `destination-branch` of `destination-repo`
|
||||||
on the base branch
|
(or a fork) is checked-out.
|
||||||
* A file with the JSON describing the pull request in the
|
* The path to a JSON file describing the pull request in `destination-repo`.
|
||||||
destination repository
|
* A directory path in which the head of `origin-repo` is checked-out at:
|
||||||
* A directory in which the origin repository is checked-out
|
* if `origin-pr` is specified, the head branch of `origin-pr`
|
||||||
on the head branch
|
* otherwise `origin-ref`
|
||||||
* A file with the JSON describing the pull request in the
|
* Information about the `origin-repo`
|
||||||
origin repository
|
* if `origin-pr` is specified, the path to a JSON file desccribing
|
||||||
|
the pull request in `origin-repo`
|
||||||
|
* otherwise `origin-ref`
|
||||||
|
|
||||||
If changes are found in the destination repository directory after the `update` script runs,
|
If changes are found in the destination repository directory after
|
||||||
they will be pushed as a new commit in the PR.
|
the `update` script runs, they will be pushed as a new commit in the
|
||||||
|
PR in the `destination-repo`.
|
||||||
|
|
||||||
`origin-token` is used when accessing `origin-repo` and needs the
|
`origin-token` is used when accessing `origin-repo` and needs the
|
||||||
`read:user`, `read:repository` and `write:issue` scopes.
|
`read:user`, `read:repository` and `write:issue` scopes.
|
||||||
|
|
||||||
`destination-token` is used to push the branch that contains an
|
`destination-token` is used to push the branch that contains an
|
||||||
update to `destination-repo` and to open a pull request. It needs
|
update to `destination-repo` (or `destination-fork-repo`) and open a
|
||||||
the `read:user`, `write:repository` and `write:issue` scopes.
|
pull request. It needs the `read:user`, `write:repository` and
|
||||||
|
`write:issue` scopes.
|
||||||
|
|
||||||
It is recommended that a dedicated user is used to create
|
It is recommended that a dedicated user is used to create
|
||||||
`destination-token` and that `destination-fork-repo` is always used
|
`destination-token` and that `destination-fork-repo` is always used
|
||||||
unless the users who are able to create pull requests are trusted.
|
unless the users who are able to create pull requests are trusted.
|
||||||
|
|
||||||
When the PR is from a forked repository, the `update` script is run
|
When the PR in the `destination-repo` is from a forked repository,
|
||||||
from the default branch of the base repository instead of the head
|
the `update` script is run from the default branch of
|
||||||
branch of the fork. The pull request author must not be trusted
|
`destination-repo` instead of the head of the PR which is a branch
|
||||||
and it is imperative that the `update` script never runs anything
|
in destination-fork-repo. The PR author must not be trusted and it
|
||||||
found in the head branch of the pull request.
|
is imperative that the `update` script never runs anything found in
|
||||||
|
the head branch of the PR.
|
||||||
|
|
||||||
If the fork of the destination repository is specified and it does
|
If the fork of the destination repository is specified and it does
|
||||||
not exist, it is created.
|
not exist, it is created.
|
||||||
|
@ -70,8 +81,9 @@ inputs:
|
||||||
description: 'a token with write permission on origin-repo'
|
description: 'a token with write permission on origin-repo'
|
||||||
required: true
|
required: true
|
||||||
origin-pr:
|
origin-pr:
|
||||||
description: 'number of the PR in {orign-repo}'
|
description: 'number of the PR in {orign-repo}, mutually exclusive with {origin-ref}'
|
||||||
required: true
|
origin-ref:
|
||||||
|
description: 'reference in {orign-repo}, mutually exclusive with {origin-pr}'
|
||||||
destination-url:
|
destination-url:
|
||||||
description: 'URL of the Forgejo instance where the cascading PR is created or updated (e.g. https://code.forgejo.org)'
|
description: 'URL of the Forgejo instance where the cascading PR is created or updated (e.g. https://code.forgejo.org)'
|
||||||
required: true
|
required: true
|
||||||
|
@ -125,6 +137,7 @@ runs:
|
||||||
--origin-repo "${{ inputs.origin-repo }}" \
|
--origin-repo "${{ inputs.origin-repo }}" \
|
||||||
--origin-token "@$origin_token" \
|
--origin-token "@$origin_token" \
|
||||||
--origin-pr "${{ inputs.origin-pr }}" \
|
--origin-pr "${{ inputs.origin-pr }}" \
|
||||||
|
--origin-ref "${{ inputs.origin-ref }}" \
|
||||||
--destination-url "${{ inputs.destination-url }}" \
|
--destination-url "${{ inputs.destination-url }}" \
|
||||||
--destination-repo "${{ inputs.destination-repo }}" \
|
--destination-repo "${{ inputs.destination-repo }}" \
|
||||||
--destination-fork-repo "${{ inputs.destination-fork-repo }}" \
|
--destination-fork-repo "${{ inputs.destination-fork-repo }}" \
|
||||||
|
|
|
@ -197,3 +197,47 @@ function wait_status() {
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sanity_check_pr_or_ref() {
|
||||||
|
local pr="$1" ref="$2"
|
||||||
|
|
||||||
|
if test "$pr" -a "$ref" ; then
|
||||||
|
log_error "--origin-pr $pr and --origin-ref $ref are mutually exclusive"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if test -z "$pr" -a -z "$ref" ; then
|
||||||
|
log_error "one of --origin-pr or --origin-ref must be set"
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function set_origin_head() {
|
||||||
|
local pr="${options[origin_pr]}"
|
||||||
|
local ref="${options[origin_ref]}"
|
||||||
|
|
||||||
|
sanity_check_pr_or_ref "$pr" "$ref"
|
||||||
|
|
||||||
|
if test "$pr"; then
|
||||||
|
options[origin_head]=refs/pull/$pr/head
|
||||||
|
origin_sanity_check
|
||||||
|
else
|
||||||
|
options[origin_head]=$ref
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function origin_has_pr() {
|
||||||
|
test "${options[origin_pr]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function set_destination_head() {
|
||||||
|
local pr="${options[origin_pr]}"
|
||||||
|
local ref="${options[origin_ref]}"
|
||||||
|
|
||||||
|
sanity_check_pr_or_ref "$pr" "$ref"
|
||||||
|
|
||||||
|
if $(origin_has_pr); then
|
||||||
|
options[destination_head]=${options[prefix]}-$pr
|
||||||
|
else
|
||||||
|
options[destination_head]=${options[prefix]}-$ref
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
|
@ -187,7 +187,7 @@ function git_checkout() {
|
||||||
(
|
(
|
||||||
cd $TMPDIR/$direction
|
cd $TMPDIR/$direction
|
||||||
if [[ "$ref" =~ ^refs/ ]] ; then
|
if [[ "$ref" =~ ^refs/ ]] ; then
|
||||||
git fetch ${remote} +$ref:$ref
|
git fetch --update-head-ok ${remote} +$ref:$ref
|
||||||
else
|
else
|
||||||
ref=${remote}/$ref
|
ref=${remote}/$ref
|
||||||
fi
|
fi
|
||||||
|
@ -305,7 +305,7 @@ function update() {
|
||||||
local update=${options[update]}
|
local update=${options[update]}
|
||||||
if ! [[ "$update" =~ ^/ ]] ; then
|
if ! [[ "$update" =~ ^/ ]] ; then
|
||||||
local d
|
local d
|
||||||
if $(pr_from_fork origin); then
|
if $(origin_has_pr) && $(pr_from_fork origin); then
|
||||||
local default_branch=$(default_branch origin)
|
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"
|
log_info "PR is from a forked repository, using the default branch $default_branch to obtain the update script"
|
||||||
d=$TMPDIR/update
|
d=$TMPDIR/update
|
||||||
|
@ -316,7 +316,13 @@ function update() {
|
||||||
update=$d/$update
|
update=$d/$update
|
||||||
fi
|
fi
|
||||||
cd $TMPDIR
|
cd $TMPDIR
|
||||||
$update $TMPDIR/destination $TMPDIR/destination-pr.json $TMPDIR/origin $TMPDIR/origin-pr.json
|
local origin_info
|
||||||
|
if $(origin_has_pr); then
|
||||||
|
origin_info=$TMPDIR/origin-pr.json
|
||||||
|
else
|
||||||
|
origin_info="${options[origin_ref]}"
|
||||||
|
fi
|
||||||
|
$update $TMPDIR/destination $TMPDIR/destination-pr.json $TMPDIR/origin $origin_info
|
||||||
)
|
)
|
||||||
local remote_head=origin
|
local remote_head=origin
|
||||||
if ${options[destination_is_fork]} ; then
|
if ${options[destination_is_fork]} ; then
|
||||||
|
@ -360,8 +366,7 @@ function finalize_options() {
|
||||||
options[origin_scheme]=$(scheme ${options[origin_url]})
|
options[origin_scheme]=$(scheme ${options[origin_url]})
|
||||||
options[origin_host_port]=$(host_port ${options[origin_url]})
|
options[origin_host_port]=$(host_port ${options[origin_url]})
|
||||||
set_git_url origin origin_clone ${options[origin_repo]}
|
set_git_url origin origin_clone ${options[origin_repo]}
|
||||||
options[origin_head]=refs/pull/${options[origin_pr]}/head
|
set_origin_head
|
||||||
origin_sanity_check
|
|
||||||
|
|
||||||
options[destination_api]=${options[destination_url]}/api/v1/repos/${options[destination_repo]}
|
options[destination_api]=${options[destination_url]}/api/v1/repos/${options[destination_repo]}
|
||||||
options[destination_scheme]=$(scheme ${options[destination_url]})
|
options[destination_scheme]=$(scheme ${options[destination_url]})
|
||||||
|
@ -369,7 +374,7 @@ function finalize_options() {
|
||||||
set_git_url destination destination_clone ${options[destination_repo]}
|
set_git_url destination destination_clone ${options[destination_repo]}
|
||||||
options[destination_base]=${options[destination_branch]}
|
options[destination_base]=${options[destination_branch]}
|
||||||
: ${options[prefix]:=${options[origin_repo]}}
|
: ${options[prefix]:=${options[origin_repo]}}
|
||||||
options[destination_head]=${options[prefix]}-${options[origin_pr]}
|
set_destination_head
|
||||||
|
|
||||||
if test "${options[destination_fork_repo]}"; then
|
if test "${options[destination_fork_repo]}"; then
|
||||||
fork_sanity_check
|
fork_sanity_check
|
||||||
|
@ -384,11 +389,39 @@ function finalize_options() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function run() {
|
function run() {
|
||||||
local state=$(pr_state origin)
|
|
||||||
|
|
||||||
repo_login origin
|
repo_login origin
|
||||||
repo_login destination
|
repo_login destination
|
||||||
|
|
||||||
|
if $(origin_has_pr); then
|
||||||
|
run_origin_pr
|
||||||
|
else
|
||||||
|
run_origin_ref
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_origin_ref() {
|
||||||
|
log_info "update or create the cascade branch and PR"
|
||||||
|
checkout
|
||||||
|
update
|
||||||
|
local sha=$(sha_pushed destination)
|
||||||
|
if test "$sha" ; then
|
||||||
|
upsert_destination_pr
|
||||||
|
local status
|
||||||
|
if wait_destination_ci "$sha" ; then
|
||||||
|
log_info "cascade PR status successful"
|
||||||
|
status=0
|
||||||
|
else
|
||||||
|
log_info "cascade PR status failed"
|
||||||
|
status=1
|
||||||
|
fi
|
||||||
|
close_pr
|
||||||
|
return $status
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_origin_pr() {
|
||||||
|
local state=$(pr_state origin)
|
||||||
|
|
||||||
case "$state" in
|
case "$state" in
|
||||||
open)
|
open)
|
||||||
log_info "PR is open, update or create the cascade branch and PR"
|
log_info "PR is open, update or create the cascade branch and PR"
|
||||||
|
@ -455,6 +488,11 @@ function main() {
|
||||||
options[origin_pr]=$1
|
options[origin_pr]=$1
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
--origin-ref)
|
||||||
|
shift
|
||||||
|
options[origin_ref]=$1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
--destination-url)
|
--destination-url)
|
||||||
shift
|
shift
|
||||||
options[destination_url]=$1
|
options[destination_url]=$1
|
||||||
|
|
8
tests/destination-fail/.forgejo/workflows/test.yml
Normal file
8
tests/destination-fail/.forgejo/workflows/test.yml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
name: test
|
||||||
|
on: [pull_request_target]
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: docker
|
||||||
|
steps:
|
||||||
|
- run: false
|
20
tests/origin-branch-fail/.forgejo/workflows/test.yml
Normal file
20
tests/origin-branch-fail/.forgejo/workflows/test.yml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
name: test
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: docker
|
||||||
|
steps:
|
||||||
|
- uses: SELF@vTest
|
||||||
|
with:
|
||||||
|
origin-url: ${{ env.GITHUB_SERVER_URL }}
|
||||||
|
origin-repo: user1/origin-branch-fail
|
||||||
|
origin-token: ${{ secrets.ORIGIN_TOKEN }}
|
||||||
|
origin-ref: refs/heads/main
|
||||||
|
destination-url: ${{ env.GITHUB_SERVER_URL }}
|
||||||
|
destination-repo: user2/destination-fail
|
||||||
|
destination-branch: main
|
||||||
|
destination-token: ${{ secrets.DESTINATION_TOKEN }}
|
||||||
|
update: ./upgraded
|
||||||
|
debug: true
|
1
tests/origin-branch-fail/README
Normal file
1
tests/origin-branch-fail/README
Normal file
|
@ -0,0 +1 @@
|
||||||
|
originrepo
|
14
tests/origin-branch-fail/upgraded
Executable file
14
tests/origin-branch-fail/upgraded
Executable file
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
destination_checkout="$1"
|
||||||
|
destination_pr_json="$2"
|
||||||
|
origin_checkout="$3"
|
||||||
|
origin_ref="$4"
|
||||||
|
|
||||||
|
test -d $destination_checkout
|
||||||
|
test -d $origin_checkout
|
||||||
|
test "$origin_ref"
|
||||||
|
|
||||||
|
date +%s > $destination_checkout/last
|
20
tests/origin-branch/.forgejo/workflows/test.yml
Normal file
20
tests/origin-branch/.forgejo/workflows/test.yml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
name: test
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: docker
|
||||||
|
steps:
|
||||||
|
- uses: SELF@vTest
|
||||||
|
with:
|
||||||
|
origin-url: ${{ env.GITHUB_SERVER_URL }}
|
||||||
|
origin-repo: user1/origin-branch
|
||||||
|
origin-token: ${{ secrets.ORIGIN_TOKEN }}
|
||||||
|
origin-ref: refs/heads/main
|
||||||
|
destination-url: ${{ env.GITHUB_SERVER_URL }}
|
||||||
|
destination-repo: user2/destinationrepo
|
||||||
|
destination-branch: main
|
||||||
|
destination-token: ${{ secrets.DESTINATION_TOKEN }}
|
||||||
|
update: ./upgraded
|
||||||
|
debug: true
|
1
tests/origin-branch/README
Normal file
1
tests/origin-branch/README
Normal file
|
@ -0,0 +1 @@
|
||||||
|
originrepo
|
14
tests/origin-branch/upgraded
Executable file
14
tests/origin-branch/upgraded
Executable file
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
destination_checkout="$1"
|
||||||
|
destination_pr_json="$2"
|
||||||
|
origin_checkout="$3"
|
||||||
|
origin_ref="$4"
|
||||||
|
|
||||||
|
test -d $destination_checkout
|
||||||
|
test -d $origin_checkout
|
||||||
|
test "$origin_ref"
|
||||||
|
|
||||||
|
date +%s > $destination_checkout/last
|
73
tests/run.sh
73
tests/run.sh
|
@ -79,17 +79,35 @@ function merge_pull_request() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function has_cascade_pull_request() {
|
function has_cascade_pull_request() {
|
||||||
log_verbose "verify a cascade pull request exists"
|
local repo="${1:-destinationrepo}"
|
||||||
test "$(cascade_pull_request_count)" -gt 0
|
|
||||||
|
log_verbose "verify an open cascade pull request exists"
|
||||||
|
test "$(cascade_open_pull_request_count $repo)" -gt 0
|
||||||
}
|
}
|
||||||
|
|
||||||
function has_no_cascade_pull_request() {
|
function has_no_cascade_pull_request() {
|
||||||
log_verbose "verify there is no cascade pull request"
|
local repo="${1:-destinationrepo}"
|
||||||
test "$(cascade_pull_request_count)" = 0
|
|
||||||
|
log_verbose "verify there is no open cascade pull request"
|
||||||
|
test "$(cascade_open_pull_request_count $repo)" = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function cascade_open_pull_request_count() {
|
||||||
|
local repo="$1"
|
||||||
|
|
||||||
|
cascade_pull_request $repo | jq '[ .[] | select(.state == "open") ] | length'
|
||||||
}
|
}
|
||||||
|
|
||||||
function cascade_pull_request_count() {
|
function cascade_pull_request_count() {
|
||||||
forgejo-curl.sh api_json ${options[url]}/api/v1/repos/user2/destinationrepo/pulls | jq '[ .[] | select(.state == "open") ] | length'
|
local repo="$1"
|
||||||
|
|
||||||
|
cascade_pull_request $repo | jq '. | length'
|
||||||
|
}
|
||||||
|
|
||||||
|
function cascade_pull_request() {
|
||||||
|
local repo="$1"
|
||||||
|
|
||||||
|
forgejo-curl.sh api_json ${options[url]}/api/v1/repos/user2/${repo}/pulls
|
||||||
}
|
}
|
||||||
|
|
||||||
function create_branch1() {
|
function create_branch1() {
|
||||||
|
@ -150,6 +168,13 @@ function create_pull_request_case1() {
|
||||||
create_pull_request $baseowner $headowner $repo
|
create_pull_request $baseowner $headowner $repo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function unit_finalize_options() {
|
||||||
|
sanity_check_pr_or_ref A B || test $? = 1
|
||||||
|
sanity_check_pr_or_ref '' '' || test $? = 2
|
||||||
|
sanity_check_pr_or_ref A ''
|
||||||
|
sanity_check_pr_or_ref '' B
|
||||||
|
}
|
||||||
|
|
||||||
function unit_retry_fail() {
|
function unit_retry_fail() {
|
||||||
local file=$1
|
local file=$1
|
||||||
local value=$(cat $file)
|
local value=$(cat $file)
|
||||||
|
@ -246,6 +271,34 @@ function no_change_no_cascade_pr() {
|
||||||
has_no_cascade_pull_request
|
has_no_cascade_pull_request
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function branch_and_success() {
|
||||||
|
local origin_repo=origin-branch
|
||||||
|
local destination_repo=destinationrepo
|
||||||
|
|
||||||
|
fixture ${origin_repo} ${destination_repo}
|
||||||
|
user_secret user1 DESTINATION_TOKEN $(user_token user2 DESTINATION_TOKEN)
|
||||||
|
|
||||||
|
test $(cascade_pull_request_count ${destination_repo}) = 0
|
||||||
|
create_branch1 user1 ${origin_repo}
|
||||||
|
wait_success ${options[url]}/api/v1/repos/user1/${origin_repo} $(cat $TMPDIR/user1-${origin_repo}.sha)
|
||||||
|
test $(cascade_pull_request_count ${destination_repo}) = 1
|
||||||
|
has_no_cascade_pull_request ${destination_repo}
|
||||||
|
}
|
||||||
|
|
||||||
|
function branch_and_fail() {
|
||||||
|
local origin_repo=origin-branch-fail
|
||||||
|
local destination_repo=destination-fail
|
||||||
|
|
||||||
|
fixture ${origin_repo} ${destination_repo}
|
||||||
|
user_secret user1 DESTINATION_TOKEN $(user_token user2 DESTINATION_TOKEN)
|
||||||
|
|
||||||
|
test $(cascade_pull_request_count ${destination_repo}) = 0
|
||||||
|
create_branch1 user1 ${origin_repo}
|
||||||
|
wait_failure ${options[url]}/api/v1/repos/user1/${origin_repo} $(cat $TMPDIR/user1-${origin_repo}.sha)
|
||||||
|
test $(cascade_pull_request_count ${destination_repo}) = 1
|
||||||
|
has_no_cascade_pull_request ${destination_repo}
|
||||||
|
}
|
||||||
|
|
||||||
function create_and_close() {
|
function create_and_close() {
|
||||||
fixture originrepo destinationrepo
|
fixture originrepo destinationrepo
|
||||||
user_secret user1 DESTINATION_TOKEN $(user_token user2 DESTINATION_TOKEN)
|
user_secret user1 DESTINATION_TOKEN $(user_token user2 DESTINATION_TOKEN)
|
||||||
|
@ -367,6 +420,7 @@ function run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function integration() {
|
function integration() {
|
||||||
|
run branch_and_success
|
||||||
run no_change_no_cascade_pr
|
run no_change_no_cascade_pr
|
||||||
run create_in_destination_fork_and_close
|
run create_in_destination_fork_and_close
|
||||||
run create_and_close
|
run create_and_close
|
||||||
|
@ -379,6 +433,7 @@ function integration() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function unit() {
|
function unit() {
|
||||||
|
unit_finalize_options
|
||||||
unit_retry
|
unit_retry
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,12 +443,12 @@ function run_tests() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function finalize_options() {
|
function finalize_options() {
|
||||||
if test -f forgejo-ip; then
|
if test -f $DIR/forgejo-ip; then
|
||||||
: ${options[host_port]:=$(cat forgejo-ip):3000}
|
: ${options[host_port]:=$(cat $DIR/forgejo-ip):3000}
|
||||||
fi
|
fi
|
||||||
options[url]=http://${options[host_port]}
|
options[url]=http://${options[host_port]}
|
||||||
if test -f forgejo-token; then
|
if test -f $DIR/forgejo-token; then
|
||||||
: ${options[token]:=$(cat forgejo-token)}
|
: ${options[token]:=$(cat $DIR/forgejo-token)}
|
||||||
fi
|
fi
|
||||||
options[password]=admin1234
|
options[password]=admin1234
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue