|
| 1 | +--- |
| 2 | +title: Orchestrate releases |
| 3 | +description: Coordinate the updates of your docs across multiple repositories and releases. |
| 4 | +--- |
| 5 | + |
| 6 | +Fern Docs supports orchestrating the release of your docs based on releases from other repositories. This is useful when you are documenting features that depend on other features that are released in other repositories. |
| 7 | + |
| 8 | +## Trigger a dispatch for a specific release tag |
| 9 | + |
| 10 | +Add the following GitHub Action workflow to the repository where the releases will be made. |
| 11 | + |
| 12 | +```yml |
| 13 | +name: Notify Docs Repo |
| 14 | +on: |
| 15 | + release: |
| 16 | + types: [created] |
| 17 | + tags: |
| 18 | + - "<PRODUCT_RELEASE_TAG>@*" |
| 19 | + |
| 20 | +jobs: |
| 21 | + notify-docs: |
| 22 | + runs-on: ubuntu-latest |
| 23 | + steps: |
| 24 | + - name: Trigger docs repo workflow |
| 25 | + run: | |
| 26 | + curl -f -X POST \ |
| 27 | + -H "Accept: application/vnd.github.v3+json" \ |
| 28 | + -H "Authorization: token ${{ secrets.<GITHUB_ACCESS_TOKEN> }}" \ |
| 29 | + https://api.github.com/repos/<ORG>/<DOCS_REPO>/dispatches \ |
| 30 | + -d '{"event_type":"<PRODUCT_RELEASE_TAG>","client_payload":{"version":"${{ github.ref_name }}"}}' |
| 31 | +``` |
| 32 | +
|
| 33 | +<Note title="Replace placeholders with your own values"> |
| 34 | +- `<GITHUB_ACCESS_TOKEN>`: A GitHub access token with the `repo` scope. |
| 35 | +- `<ORG>`: The organization that contains the docs repository. |
| 36 | +- `<DOCS_REPO>`: The name of the docs repository. |
| 37 | +- `<PRODUCT_RELEASE_TAG>`: The tag of the product release. |
| 38 | +</Note> |
| 39 | + |
| 40 | +## Merge dependent PRs |
| 41 | + |
| 42 | +```yml |
| 43 | +# .github/workflows/auto-merge-on-release.yml in docs repo |
| 44 | +name: Auto-merge on Docs Release |
| 45 | +on: |
| 46 | + repository_dispatch: |
| 47 | + types: [<PRODUCT_RELEASE_TAG>] |
| 48 | +
|
| 49 | +jobs: |
| 50 | + merge-dependent-prs: |
| 51 | + runs-on: ubuntu-latest |
| 52 | + steps: |
| 53 | + - name: Find and merge dependent PRs |
| 54 | + uses: actions/github-script@v7 |
| 55 | + with: |
| 56 | + script: | |
| 57 | + const version = context.payload.client_payload.version; |
| 58 | + |
| 59 | + // Find PRs with matching labels |
| 60 | + const { data: prs } = await github.rest.pulls.list({ |
| 61 | + owner: context.repo.owner, |
| 62 | + repo: context.repo.repo, |
| 63 | + state: 'open' |
| 64 | + }); |
| 65 | + |
| 66 | + for (const pr of prs) { |
| 67 | + const labels = pr.labels.map(l => l.name); |
| 68 | + const hasLatestLabel = labels.includes('depends-on: <PRODUCT_RELEASE_TAG>@latest'); |
| 69 | + const hasVersionLabel = labels.includes(`depends-on: <PRODUCT_RELEASE_TAG>@${version}`); |
| 70 | + |
| 71 | + if (hasLatestLabel || hasVersionLabel) { |
| 72 | + // Check if PR is approved and CI passes |
| 73 | + const { data: reviews } = await github.rest.pulls.listReviews({ |
| 74 | + owner: context.repo.owner, |
| 75 | + repo: context.repo.repo, |
| 76 | + pull_number: pr.number |
| 77 | + }); |
| 78 | + |
| 79 | + const approved = reviews.some(r => r.state === 'APPROVED'); |
| 80 | + |
| 81 | + if (approved) { |
| 82 | + await github.rest.pulls.merge({ |
| 83 | + owner: context.repo.owner, |
| 84 | + repo: context.repo.repo, |
| 85 | + pull_number: pr.number, |
| 86 | + merge_method: 'squash' |
| 87 | + }); |
| 88 | + |
| 89 | + console.log(`Merged PR #${pr.number}: ${pr.title}`); |
| 90 | + } |
| 91 | + } |
| 92 | + } |
| 93 | +``` |
| 94 | + |
| 95 | +<Note title="Replace placeholders with your own values"> |
| 96 | +- `<PRODUCT_RELEASE_TAG>`: The tag of the product release. |
| 97 | +</Note> |
0 commit comments