1
0
Fork 0
mirror of https://code.forgejo.org/actions/cascading-pr synced 2025-03-15 06:46:59 +01:00
cascading-pr/README.md

233 lines
9.6 KiB
Markdown
Raw Normal View History

2023-10-11 18:09:39 +02:00
Create and synchronize a PR in a dependent repository
2023-10-11 15:39:52 +02:00
2023-10-13 23:38:57 +02:00
<!-- action-docs-description -->
## 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.
2023-10-13 23:38:57 +02:00
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.
2023-10-13 23:38:57 +02:00
The `update` script is expected to be found in the origin repository
running the PR. It is given four arguments:
2023-10-13 23:38:57 +02:00
* A directory in which the destination repository (or a fork) is checked-out
on the base branch
2023-10-13 23:38:57 +02:00
* 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
2023-10-13 23:38:57 +02:00
* 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.
2023-10-13 23:38:57 +02:00
<!-- action-docs-description -->
<!-- action-docs-inputs -->
## Inputs
| parameter | description | required | default |
| --- | --- | --- | --- |
| 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-token | a token with write permission on origin-repo | `true` | |
| origin-pr | number of the PR in {orign-repo} | `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-fork-repo | the fork of {destination-repo} in which the {destination-branch} will be created or updated | `false` | |
2023-10-13 23:38:57 +02:00
| destination-branch | the base branch of the destination repository for the cascading PR | `true` | |
| destination-token | a token with write permission on destination-repo | `true` | |
| update | path to the script to update the content of the cascading PR | `true` | |
| prefix | prefix of the cascading PR created on destination-repo (default to {origin-repo}) | `false` | |
| close-merge | if true the cascading PR will be closed and the branch deleted when the PR is merged | `false` | false |
2023-10-13 23:38:57 +02:00
| verbose | if true print verbose information | `false` | false |
| debug | if true print debug information | `false` | false |
<!-- action-docs-inputs -->
# Forgejo dependencies
The [Forgejo](https://codeberg.org/forgejo/forgejo/) repositories that depend on each other are
linked with workflows using `cascading-pr` as follows.
```mermaid
flowchart TD
lxc-helper(lxc-helper) --> act(act)
act --> runner(Forgejo runner)
runner --> setup-forgejo(setup-forgejo)
setup-forgejo --> e2e(end-to-end)
forgejo-curl(forgejo-curl.sh) --> setup-forgejo
forgejo(forgejo) --> e2e
click lxc-helper "https://code.forgejo.org/forgejo/lxc-helpers/src/branch/main/.forgejo/workflows/cascade-act.yml"
click act "https://code.forgejo.org/forgejo/act/src/branch/main/.forgejo/workflows/cascade-runner.yml"
click runner "https://code.forgejo.org/forgejo/runner/src/branch/main/.forgejo/workflows/cascade-setup-forgejo.yml"
click setup-forgejo "https://code.forgejo.org/actions/setup-forgejo/src/branch/main/.forgejo/workflows/cascade-end-to-end.yml"
click e2e "https://code.forgejo.org/actions/end-to-end"
click forgejo-curl "https://code.forgejo.org/forgejo/forgejo-curl/src/branch/main/.forgejo/workflows/cascade-setup-forgejo.yml"
click forgejo "https://codeberg.org/forgejo/forgejo/src/branch/forgejo/.forgejo/workflows/cascade-setup-end-to-end.yml"
```
# Example workflow
2023-10-13 23:38:57 +02:00
```yaml
on:
pull_request:
types:
- opened
- synchronize
- closed
jobs:
test:
runs-on: docker
steps:
- uses: actions/checkout@v4
- uses: actions/cascading-pr@v1
with:
origin-url: https://code.forgejo.org
origin-repo: forgejo/lxc-helpers
origin-token: ${{ secrets.ORIGIN_TOKEN }}
origin-pr: ${{ github.event.pull_request.number }}
destination-url: https://code.forgejo.org
destination-repo: forgejo/act
2023-10-13 23:38:57 +02:00
destination-branch: main
destination-token: ${{ secrets.DESTINATION_TOKEN }}
update: ./upgrade-lxc-helpers
```
# Pull requests from forked repositories
When `cascading-pr` runs as a consequence of pull request from a
forked repository, the workflow must be triggered by a `pull_request_target`
event otherwise it will not have access to secrets.
# Prevent privilege escalation
When `cascading-pr` runs as a consequence of a pull request from a
repository forked from `orgin-repo`, it should create a pull request
from a forked repository of `destination-repo` by specifying the
`destination-fork-repo`.
If the `destination-fork-repo` repository does not exist, it will be
created as a fork of the `destination-repo` repository, using
`destination-token`.
2023-10-11 15:39:52 +02:00
# Hacking
The test environment consists of the following (all users password is admin1234)
2023-10-13 14:54:56 +02:00
* A forgejo instance with a runner
* An unprivileged user user1
* The repository user1/originrepo
* contains a pull_request workflow using cascading-pr that targets user2/destinationrepo
* contains a script that will modify user2/destinationrepo
2023-10-13 15:23:50 +02:00
* a branch1 at the same commit as main
2023-10-13 14:54:56 +02:00
* The repository user1/cascading-pr with the action under test
* An unprivileged user user2
* The repository user2/destinationrepo
2023-10-22 17:25:03 +02:00
```sh
git clone https://code.forgejo.org/actions/setup-forgejo
export PATH=$(pwd)/setup-forgejo:$PATH
git clone https://code.forgejo.org/actions/cascading-pr
cd cascading-pr
forgejo-curl.sh logout
forgejo-runner.sh teardown
forgejo.sh teardown
forgejo.sh setup root admin1234 codeberg.org/forgejo/forgejo 1.21
FORGEJO_RUNNER_CONFIG=$(pwd)/tests/runner-config.yaml forgejo-runner.sh setup
url=http://$(cat forgejo-ip):3000
firefox $url
```
2023-10-13 15:23:50 +02:00
The test for a successful run of the cascading-pr action consists of:
* creating a PR from branch1 to main
* wait for the commit status until it is successful
2023-10-13 14:54:56 +02:00
## testing an update on the action
* run `tests/run.sh --debug` once so all is in place
* commit changes to the files that are in the cascading-pr action
(action.yml, cascading-pr.sh etc.)
* push the modified action to `user1/cascading-pr`
* visit $url/user1/originrepo/actions/runs/1 and click re-run
## interactive debugging
Following the steps below recreate the same environment as the
integration workflow locally. It is helpful for forensic analysis when
something does not run as expected and the error displayed are unclear.
To help with the development loop all steps are idempotent and
running `tests/run.sh --debug` multiple times must succeed.
Individual steps can be run independendely by using the name of the function.
For instance:
* `tests/run.sh --debug create_pull_request` will only call the `create_pull_request`
function found in `tests/run.sh` to (re)create the pull request in `user1/originrepo`.
* `./cascading-pr.sh --debug --origin-url ... upsert_branch` will only call the `upsert_branch`
function found in `cascading-pr.sh`.
## directories
The `tests/run.sh` script stores all its files in
`/tmp/cascading-pr-test`. The temporary directories created by
`cascading-pr.sh` are disposed of when the script ends.
## logging
If `--debug` is used a full debug log is displayed, very complete and
very verbose. Otherwise it is stashed in a temporary file and only
displayed if an error happens.
## snippets for copy/pasting
2023-10-11 15:39:52 +02:00
```sh
2023-10-11 16:25:56 +02:00
tests/run.sh --debug
tests/run.sh --debug no_change_no_cascade_pr
2023-10-13 14:54:56 +02:00
./cascading-pr.sh --debug --origin-url "$url" --origin-repo "user1/originrepo" --origin-token "$(cat /tmp/cascading-pr-test/user1/repo-token)" --origin-pr 1 --destination-url "$url" --destination-repo "user2/destinationrepo" --destination-token "$(cat /tmp/cascading-pr-test/user2/repo-token)" --destination-branch "main" --update "upgraded" run
2023-10-11 15:39:52 +02:00
```
2023-10-13 23:38:57 +02:00
## Update the README
With https://github.com/npalm/action-docs `action-docs --update-readme`