# 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 it will upgrade with the proposed change from repository B. When used in a workflow triggered by a PR event in `origin-repo`, `cascading-pr` will create, update and close a matching PR in another repository (`destination-repo`). When the PR is updated, `cascading-pr` subsequently will update the matching PR. The worfklows in `origin-repo` will wait for the workflow in `destination-repo` to complete. If the workflow in `destination-repo` fails, the workflow in `origin-repo` will also fail. 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. `cascading-pr` will wait until the CI in `actions/setup-forgejo` is successful. 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 (or a fork) 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 after the `update` script runs, they will be pushed as a new commit in the PR. `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` and to 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 is from a forked repository, the `update` script is run from the default branch of the base repository instead of the head branch of the fork. The pull request author must not be trusted and it is imperative that the `update` script never runs anything found in the head branch of the pull request. 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}' required: true 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 cascading PR created on destination-repo (default to {origin-repo})' close-merge: description: 'if true the cascading PR will be closed and the branch deleted when the PR is merged' default: false verbose: description: 'if true print verbose information' default: false debug: description: 'if true print debug information' default: false runs: using: "composite" steps: - uses: actions/checkout@v4 - 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 }}" \ --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-merge "${{ inputs.close-merge }}" \ run