sync-team dry-run #6
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This workflow executes a dry-run of the sync-team tool after a push to any pull request. | |
# This allows us to see which changes would be applied to live services after the PR | |
# would be merged. | |
# | |
# The workflow uses the `workflow_run` trigger, which should always run in the default branch of | |
# this repository. This is required so that the workflow has permissions to post PR comments. | |
# We should not check out any code from the PR, as it could present a security hazard. | |
# Instead, we simply download a GitHub artifact with a directory of JSON files and use that as | |
# input for sync-team. | |
# This artifact is created and uploaded on PR pushes using the CI workflow in `main.yml`. | |
# Details about `workflow_run`: | |
# https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#workflow_run: | |
name: sync-team dry-run | |
on: | |
workflow_run: | |
workflows: [ CI ] | |
types: | |
- completed | |
concurrency: | |
# Only run this once at a time on any given PR | |
group: dry-run-${{ github.event.workflow_run.pull_requests[0].number }} | |
cancel-in-progress: true | |
jobs: | |
dry-run: | |
runs-on: ubuntu-latest | |
if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'pull_request' }} | |
permissions: | |
pull-requests: write | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
repository: rust-lang/sync-team | |
persist-credentials: false | |
- name: Install Rust Stable | |
run: | | |
rustc -vV | |
rustup update stable | |
rustup default stable | |
rustc -vV | |
- uses: Swatinem/rust-cache@v2 | |
- name: Download built JSON API | |
uses: actions/download-artifact@v4 | |
with: | |
name: team-api-output | |
path: team-api | |
run-id: ${{ github.event.workflow_run.id }} | |
github-token: ${{ secrets.GITHUB_TOKEN }} | |
# GitHub tokens generated from GitHub Apps can access resources from one organization, | |
# so we need to generate a token for each organization. | |
- name: Generate GitHub token (rust-lang) | |
uses: actions/create-github-app-token@v1 | |
id: rust-lang-token | |
with: | |
# GitHub App ID secret name | |
app-id: ${{ secrets.SYNC_TEAM_GH_APP_ID }} | |
# GitHub App private key secret name | |
private-key: ${{ secrets.SYNC_TEAM_GH_APP_PRIVATE_KEY }} | |
# Set the owner, so the token can be used in all repositories | |
owner: rust-lang | |
- name: Generate GitHub token (rust-lang-ci) | |
uses: actions/create-github-app-token@v1 | |
id: rust-lang-ci-token | |
with: | |
app-id: ${{ secrets.SYNC_TEAM_GH_APP_ID }} | |
private-key: ${{ secrets.SYNC_TEAM_GH_APP_PRIVATE_KEY }} | |
owner: rust-lang-ci | |
- name: Generate GitHub token (rust-lang-deprecated) | |
uses: actions/create-github-app-token@v1 | |
id: rust-lang-deprecated-token | |
with: | |
app-id: ${{ secrets.SYNC_TEAM_GH_APP_ID }} | |
private-key: ${{ secrets.SYNC_TEAM_GH_APP_PRIVATE_KEY }} | |
owner: rust-lang-deprecated | |
- name: Generate GitHub token (rust-lang-nursery) | |
uses: actions/create-github-app-token@v1 | |
id: rust-lang-nursery-token | |
with: | |
app-id: ${{ secrets.SYNC_TEAM_GH_APP_ID }} | |
private-key: ${{ secrets.SYNC_TEAM_GH_APP_PRIVATE_KEY }} | |
owner: rust-lang-nursery | |
- name: Generate GitHub token (bors-rs) | |
uses: actions/create-github-app-token@v1 | |
id: bors-rs-token | |
with: | |
app-id: ${{ secrets.SYNC_TEAM_GH_APP_ID }} | |
private-key: ${{ secrets.SYNC_TEAM_GH_APP_PRIVATE_KEY }} | |
owner: bors-rs | |
- name: Generate GitHub token (rust-analyzer) | |
uses: actions/create-github-app-token@v1 | |
id: rust-analyzer-token | |
with: | |
app-id: ${{ secrets.SYNC_TEAM_GH_APP_ID }} | |
private-key: ${{ secrets.SYNC_TEAM_GH_APP_PRIVATE_KEY }} | |
owner: rust-analyzer | |
- name: Generate GitHub token (rust-embedded) | |
uses: actions/create-github-app-token@v1 | |
id: rust-embedded-token | |
with: | |
app-id: ${{ secrets.SYNC_TEAM_GH_APP_ID }} | |
private-key: ${{ secrets.SYNC_TEAM_GH_APP_PRIVATE_KEY }} | |
owner: rust-embedded | |
- name: Generate GitHub token (rust-dev-tools) | |
uses: actions/create-github-app-token@v1 | |
id: rust-dev-tools-token | |
with: | |
app-id: ${{ secrets.SYNC_TEAM_GH_APP_ID }} | |
private-key: ${{ secrets.SYNC_TEAM_GH_APP_PRIVATE_KEY }} | |
owner: rust-dev-tools | |
- name: Run sync-team dry-run check | |
env: | |
GITHUB_TOKEN_RUST_LANG: ${{ steps.rust-lang-token.outputs.token }} | |
GITHUB_TOKEN_RUST_LANG_CI: ${{ steps.rust-lang-ci-token.outputs.token }} | |
GITHUB_TOKEN_RUST_LANG_DEPRECATED: ${{ steps.rust-lang-deprecated-token.outputs.token }} | |
GITHUB_TOKEN_RUST_LANG_NURSERY: ${{ steps.rust-lang-nursery-token.outputs.token }} | |
GITHUB_TOKEN_BORS_RS: ${{ steps.bors-rs-token.outputs.token }} | |
GITHUB_TOKEN_RUST_ANALYZER: ${{ steps.rust-analyzer-token.outputs.token }} | |
GITHUB_TOKEN_RUST_EMBEDDED: ${{ steps.rust-embedded-token.outputs.token }} | |
GITHUB_TOKEN_RUST_DEV_TOOLS: ${{ steps.rust-dev-tools-token.outputs.token }} | |
run: | | |
# Perform build and execution separately to avoid any potential output from | |
# cargo leaking into the output file. | |
cargo build ./target/debug/sync-team print-plan --services github --team-json team-api > output.txt | |
- name: Prepare comment | |
run: | | |
cat > comment.txt << EOL | |
<details> | |
<summary>Dry-run check results</summary> | |
<pre><code> | |
EOL | |
cat output.txt >> comment.txt | |
printf "</pre></code>\n</details>\n" >> comment.txt | |
cat comment.txt | |
- name: Send comment | |
env: | |
GH_TOKEN: ${{ github.token }} | |
run: | | |
PR=${{ github.event.workflow_run.pull_requests[0].number }} | |
# --edit-last doesn't work if there is no previous comment, so we have to figure out | |
# if we should create a comment or not | |
if gh issue view ${PR} --json comments \ | |
--jq '.comments.[].author.login' | grep --quiet --fixed-strings "github-actions"; then | |
echo "Editing comment" | |
gh pr comment ${PR} --body-file comment.txt --edit-last | |
else | |
echo "Creating new comment" | |
gh pr comment ${PR} --body-file comment.txt | |
fi |