Repository navigation
deploy #9
This file contains hidden or 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
| name: deploy | |
| # The controller, deployed from GitHub. Every push to main whose tests pass goes live by itself: | |
| # once the test workflow succeeds, this restarts the controller onto main (running turns finish | |
| # first) and waits for the next start to go live, failing — with how the start went, the boot lines | |
| # only, since this log is public — unless it includes that commit. The pull gate and the launcher | |
| # keep a bad build from taking the bot down (README: "When a deploy goes wrong"). The secrets live | |
| # in the `production` environment, which only main may deploy, never on anyone's machine. By hand: | |
| # restart pull main and restart onto it | |
| # handover give the controller its tokens and keys from the environment (after a rotation, or | |
| # for a new controller box) | |
| # rollback run an earlier commit of main until the next deploy | |
| on: | |
| workflow_run: | |
| workflows: [test] | |
| types: [completed] | |
| branches: [main] | |
| workflow_dispatch: | |
| inputs: | |
| action: | |
| description: restart · handover · rollback | |
| type: choice | |
| options: [restart, handover, rollback] | |
| default: restart | |
| commit: | |
| description: 'rollback only: the commit of main to run' | |
| required: false | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: deploy | |
| cancel-in-progress: false | |
| jobs: | |
| deploy: | |
| # By itself: only for a push to main whose tests passed — never for a PR's branch, whatever it's called. | |
| if: github.event_name == 'workflow_dispatch' || (github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push') | |
| runs-on: ubuntu-latest | |
| environment: production | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.event.workflow_run.head_sha || github.sha }} | |
| persist-credentials: false | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: 24 | |
| - name: Hand over tokens and keys | |
| if: inputs.action == 'handover' | |
| env: | |
| BOXLITE_API_KEY: ${{ secrets.BOXLITE_API_KEY }} | |
| GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }} | |
| GITHUB_APP_ID: ${{ vars.PUSH_APP_ID }} | |
| PUSH_APP_PRIVATE_KEY: ${{ secrets.PUSH_APP_PRIVATE_KEY }} | |
| SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} | |
| SLACK_APP_TOKEN: ${{ secrets.SLACK_APP_TOKEN }} | |
| SLACK_CONTEXT_SECRET: ${{ secrets.SLACK_CONTEXT_SECRET }} | |
| BOT_ADMINS: ${{ vars.BOT_ADMINS }} | |
| run: | | |
| node deploy/ctl.mjs github-token | |
| umask 077 | |
| key="$RUNNER_TEMP/push-app.pem" | |
| printf '%s\n' "$PUSH_APP_PRIVATE_KEY" > "$key" | |
| GITHUB_APP_KEY="$key" node deploy/ctl.mjs github-app | |
| rm -f "$key" | |
| if [ -n "$SLACK_BOT_TOKEN" ]; then node deploy/ctl.mjs slack-tokens; fi | |
| node deploy/ctl.mjs hook | |
| node deploy/ctl.mjs admins "$BOT_ADMINS" --includes "$GITHUB_SHA" | |
| - name: Restart onto main | |
| if: github.event_name == 'workflow_run' || inputs.action == 'restart' | |
| env: | |
| BOXLITE_API_KEY: ${{ secrets.BOXLITE_API_KEY }} | |
| COMMIT: ${{ github.event.workflow_run.head_sha || github.sha }} | |
| run: node deploy/ctl.mjs restart --includes "$COMMIT" | |
| - name: Roll back | |
| if: inputs.action == 'rollback' | |
| env: | |
| BOXLITE_API_KEY: ${{ secrets.BOXLITE_API_KEY }} | |
| COMMIT: ${{ inputs.commit }} | |
| run: node deploy/ctl.mjs rollback "$COMMIT" --wait |