inbox.yml
Org-wide prioritised PR inbox on GitHub Pages. Lives in this (source) repo.
What this is
Rebuilds the org-wide prioritised PR inbox and publishes it to GitHub Pages, via scripts/build-inbox.mjs.
How to onboard it
It lives in this repository and is already installed here. Before it will build, set the repository variable PAGES_VISIBILITY_ACKNOWLEDGED to private or internal and provide REDLINE_ORG_READ_TOKEN.
- Lives in: This (source) repo.
- Trigger: Every 30 minutes, 06:00-19:00 UTC, Monday-Friday, plus workflow_dispatch.
How to use it
Nothing, normally — it runs itself. Run scripts/build-inbox.mjs locally with a scoped GH_TOKEN to preview a layout change before it ships.
What a run does, in order:
- Refuses to build unless the repository variable PAGES_VISIBILITY_ACKNOWLEDGED is set to private or internal — the page lists PR titles, authors and repo names, and a public Pages site would leak them.
- Builds dist/index.html with scripts/build-inbox.mjs.
- Deploys to GitHub Pages, then opens or updates a tracking issue if the build or deploy failed.
Works, once Pages visibility is acknowledged and REDLINE_ORG_READ_TOKEN is set.
Expected output
A static page on GitHub Pages listing open org pull requests in priority order. On a build or deploy failure it opens or updates a single tracking issue rather than failing silently. Without the visibility acknowledgement it refuses to build at all — the page carries PR titles, authors and repo names, and a public Pages site would leak them.
How to edit it
- Edit the YAML in workflows/ or .github/workflows/workflows/ holds files destined for other repositories; .github/workflows/ is this repository's own CI. The two are not interchangeable — check where this one lives before editing.
- actionlintCI lints .github/workflows/*.yml, workflows/*.yml and templates/redline.yml together. workflows/ is pointed at explicitly because actionlint's own discovery would skip it.
- node scripts/check-pins.mjsIf you add a third-party action, pin it to a 40-character commit SHA with a trailing # vX.Y.Z comment. First-party actions/* are referenced by tag. The pin checker re-resolves the SHA against the tag the comment claims.
- node scripts/validate.mjsAsserts the workflow files the bundle depends on still exist, and that the gate's job ids still match the required check name derived from them.
The full file
# Lives in the Redline source repo. Rebuilds the org-wide PR inbox on a schedule and
# publishes it to GitHub Pages.
#
# SECURITY: the page lists PR titles, authors and repo names. Set the Pages site to
# private or internal visibility (Settings > Pages > Visibility) BEFORE enabling this.
# On a public Pages site this publishes internal delivery detail to the internet. The
# build refuses to run until PAGES_VISIBILITY_ACKNOWLEDGED is set as a repo variable.
name: Redline Inbox
on:
schedule:
- cron: '*/30 6-19 * * 1-5'
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: inbox
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Confirm Pages visibility was reviewed
env:
ACK: ${{ vars.PAGES_VISIBILITY_ACKNOWLEDGED }}
run: |
if [[ "${ACK:-}" != "private" && "${ACK:-}" != "internal" ]]; then
echo "::error::Set the repository variable PAGES_VISIBILITY_ACKNOWLEDGED to 'private' or 'internal' after confirming the Pages site is not public. This page exposes org-wide PR titles and authors."
exit 1
fi
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- name: Install and build
run: |
npm ci
npm run build
# This one runs in the source repo, so it uses the build it is about to
# ship rather than the last published package: a broken inbox here is a
# broken command, and finding that out from the release is too late.
- name: Build inbox
env:
GH_TOKEN: ${{ secrets.REDLINE_ORG_READ_TOKEN }}
run: |
node dist/bin/redline.js metrics inbox \
--org "${{ github.repository_owner }}" \
--out dist
- uses: actions/upload-pages-artifact@v3
with:
path: dist
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- id: deployment
uses: actions/deploy-pages@v4
# A silently stale inbox is worse than no inbox: people trust a page that stopped
# updating three weeks ago. Surface the failure where someone will see it.
alert:
needs: [build, deploy]
if: failure()
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
steps:
- name: Open or update a failure issue
env:
GH_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
RUN: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
set -euo pipefail
title="Redline inbox build is failing"
existing=$(gh issue list --repo "$REPO" --state open --search "$title in:title" --json number --jq '.[0].number // ""')
if [[ -n "$existing" ]]; then
gh issue comment "$existing" --repo "$REPO" --body "Still failing: $RUN"
else
gh issue create --repo "$REPO" --title "$title" \
--body "The scheduled inbox build failed. The published page is now stale. Run: $RUN"
fi