Org description drift #2
Workflow file for this run
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
| # The org description is the only unversioned string in this estate and it has the | |
| # widest reach of anything published. It lives in organisation settings: no file, no | |
| # commit, no history, and one settings click reverts any correction with no diff. | |
| # | |
| # THIS CANNOT BE A GATE. The string changes outside git, so no pull_request check can | |
| # prevent the change. This is a DRIFT DETECTOR and its detection lag is the schedule | |
| # interval. Read a green run as "it matched when we last looked", never as "it cannot | |
| # be changed". | |
| # | |
| # KNOWN DECAY, and it is the reason this file says so in a comment: GitHub disables | |
| # scheduled workflows in a repository with no activity for 60 days. This repository is | |
| # deliberately low-activity. When the cron stops, nothing announces it, and a detector | |
| # that has silently stopped is indistinguishable from one that keeps finding nothing. | |
| # Re-run it by hand from the Actions tab if this repo has been quiet, and treat the | |
| # absence of recent runs as the signal it is. | |
| name: Org description drift | |
| on: | |
| schedule: | |
| - cron: '17 13 * * *' | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| jobs: | |
| check: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Compare the live org description against the committed expectation | |
| id: compare | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| set -euo pipefail | |
| # $( ) strips trailing newlines from both sides, so the file may end with one. | |
| expected="$(cat org-description.expected.txt)" | |
| live="$(gh api /orgs/observer-protocol --jq '.description')" | |
| if [ -z "$live" ]; then | |
| echo "::error::The org description read back EMPTY. Refusing to treat that as a match." | |
| echo "drift=read-failed" >> "$GITHUB_OUTPUT" | |
| exit 1 | |
| fi | |
| if [ "$expected" = "$live" ]; then | |
| echo "Match." | |
| echo " $live" | |
| exit 0 | |
| fi | |
| echo "::error::The org description has drifted from org-description.expected.txt" | |
| printf 'expected: %s\n' "$expected" | |
| printf 'live: %s\n' "$live" | |
| { | |
| echo "### Org description drift" | |
| echo | |
| echo '**expected** (`org-description.expected.txt`)' | |
| echo | |
| echo '```'; printf '%s\n' "$expected"; echo '```' | |
| echo | |
| echo '**live** (organisation settings)' | |
| echo | |
| echo '```'; printf '%s\n' "$live"; echo '```' | |
| echo | |
| echo 'Someone changed it in settings, or a correction landed here and was never applied.' | |
| echo 'Decide which is right, then make the other match. Do not just re-commit the live value.' | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| echo "drift=yes" >> "$GITHUB_OUTPUT" | |
| exit 1 | |
| - name: Notify | |
| if: failure() | |
| env: | |
| NTFY_TOPIC: ${{ secrets.NTFY_TOPIC }} | |
| run: | | |
| set -uo pipefail | |
| # A red cron job nobody reads is the classic inert control, which is why this | |
| # step exists. If the transport is not configured, say so in the log rather | |
| # than failing quietly: the job has already failed, and a missing notification | |
| # must not look like a delivered one. | |
| if [ -z "${NTFY_TOPIC:-}" ]; then | |
| echo "::warning::NTFY_TOPIC is not set. The check failed and NOBODY WAS TOLD." | |
| exit 0 | |
| fi | |
| curl -fsS \ | |
| -H "Title: OP org description drifted" \ | |
| -H "Priority: high" \ | |
| -H "Tags: warning" \ | |
| -d "The GitHub org description no longer matches org-description.expected.txt. Run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ | |
| "https://ntfy.sh/${NTFY_TOPIC}" \ | |
| || echo "::warning::ntfy POST failed. The check failed and the notification did not go out." |