cascading-pr/action.yml
Earl Warren cf57fd2dc4
All checks were successful
integration / integration (pull_request) Successful in 13m29s
do not call actions/checkout
it is the responsibility of the caller and doing it in the action may interfere
2024-02-19 12:36:39 +01:00

149 lines
6.5 KiB
YAML

# SPDX-License-Identifier: MIT
name: 'Cascading PR'
author: 'Forgejo authors'
description: |
If repository A depends on repository B, `cascadinging-pr` can be used
by a workflow in repository B to trigger the CI on repository A and
verify it passes when using a modified version of repository B. This
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`,
`cascading-pr` will create, update and close a matching PR in the
`destination-repo`. When the PR is updated, `cascading-pr` will
update the matching PR. It waits for the workflow triggered by these
updates in `destination-repo` to complete. If fails, `cascading-pr`,
also fails.
As an example, when a PR is created in
[`forgejo/runner`](https://code.forgejo.org/forgejo/runner/), a
matching PR is created in
[`actions/setup-forgejo`](https://code.forgejo.org/actions/setup-forgejo/)
with the proposed change and `cascading-pr` waits until the CI in
`actions/setup-forgejo` is successful.
The `update` script is expected to be found in `origin-repo` and is
given the following arguments:
* A directory path in which the `destination-branch` of `destination-repo`
(or a fork) is checked-out.
* The path to a JSON file describing the pull request in `destination-repo`.
* A directory path in which the head of `origin-repo` is checked-out at:
* if `origin-pr` is specified, the head branch of `origin-pr`
* otherwise `origin-ref`
* Information about the `origin-repo`
* 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, 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
`read:user`, `read:repository` and `write:issue` scopes.
`destination-token` is used to push the branch that contains an
update to `destination-repo` (or `destination-fork-repo`) and open a
pull request. It needs the `read:user`, `write:repository` and
`write:issue` scopes.
It is recommended that a dedicated user is used to create
`destination-token` and that `destination-fork-repo` is always used
unless the users who are able to create pull requests are trusted.
When the PR in the `destination-repo` is from a forked repository,
the `update` script is run from the default branch of
`destination-repo` instead of the head of the PR which is a branch
in destination-fork-repo. The PR author must not be trusted and it
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
not exist, it is created.
inputs:
origin-url:
description: 'URL of the Forgejo instance where the PR that triggers the action is located (e.g. https://code.forgejo.org)'
required: true
origin-repo:
description: 'the repository in which the PR was created'
required: true
origin-token:
description: 'a token with write permission on origin-repo'
required: true
origin-pr:
description: 'number of the PR in {orign-repo}, mutually exclusive with {origin-ref}'
origin-ref:
description: 'reference in {orign-repo}, mutually exclusive with {origin-pr}'
destination-url:
description: 'URL of the Forgejo instance where the cascading PR is created or updated (e.g. https://code.forgejo.org)'
required: true
destination-repo:
description: 'the repository in which the cascading PR is created or updated'
required: true
destination-fork-repo:
description: 'the fork of {destination-repo} in which the {destination-branch} will be created or updated'
destination-branch:
description: 'the base branch of the destination repository for the cascading PR'
required: true
destination-token:
description: 'a token with write permission on destination-repo'
required: true
update:
description: 'path to the script to update the content of the cascading PR'
required: true
prefix:
description: 'prefix of the branch from which the cascading PR is created on {destination-repo} or {destination-fork-repo} (default to {origin-repo})'
close:
description: 'if true the cascading PR will be closed and the branch deleted when (i) the {origin-pr} is merged or (ii) when the cascading PR status is success if {origin-ref} is set'
default: false
verbose:
description: 'if true print verbose information'
default: false
debug:
description: 'if true print debug information'
default: false
runs:
using: "composite"
steps:
- run: |
export PATH=${{ github.action_path }}:$PATH
if "${{ inputs.verbose }}"; then
verbosity="$verbosity --verbose"
fi
if "${{ inputs.debug }}"; then
verbosity="$verbosity --debug"
fi
origin_token=$(pwd)/origin.token
echo -n ${{ inputs.origin-token }} > $origin_token
destination_token=$(pwd)/destination.token
echo -n ${{ inputs.destination-token }} > $destination_token
cascading-pr.sh $verbosity \
--origin-url "${{ inputs.origin-url }}" \
--origin-repo "${{ inputs.origin-repo }}" \
--origin-token "@$origin_token" \
--origin-pr "${{ inputs.origin-pr }}" \
--origin-ref "${{ inputs.origin-ref }}" \
--destination-url "${{ inputs.destination-url }}" \
--destination-repo "${{ inputs.destination-repo }}" \
--destination-fork-repo "${{ inputs.destination-fork-repo }}" \
--destination-token "@$destination_token" \
--destination-branch "${{ inputs.destination-branch }}" \
--update "${{ inputs.update }}" \
--prefix "${{ inputs.prefix }}" \
--close "${{ inputs.close }}" \
run