Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ permissions:
jobs:
empty-diff:
if: github.event_name == 'pull_request'
uses: Glyndor/.github/.github/workflows/empty-diff.yml@c958978687af37dc2d826a967d9c549589afb39f # v1.14.1
uses: Glyndor/.github/.github/workflows/empty-diff.yml@d5041b038b7d4935e75400dff612962e6fa14893 # v1.21.0

pin-policy:
uses: Glyndor/.github/.github/workflows/pin-policy-reusable.yml@8517d94fde00466f59b95c5d1bd838e2ad24a8bf # v1.15.2
uses: Glyndor/.github/.github/workflows/pin-policy-reusable.yml@d5041b038b7d4935e75400dff612962e6fa14893 # v1.21.0

# Lint and test the Python scripts that this repository ships. The
# job name is `tests`; python-ci.yml's inner job name is `Lint & test`;
Expand All @@ -44,7 +44,7 @@ jobs:
# rename that breaks the four consumer repositories. The 90% gate is
# a follow-up after the rename.
tests:
uses: Glyndor/.github/.github/workflows/python-ci.yml@7099f8a9c8be91fa1732fe2402268b338771233f # v1.15.0
uses: Glyndor/.github/.github/workflows/python-ci.yml@d5041b038b7d4935e75400dff612962e6fa14893 # v1.21.0
with:
coverage-threshold: 0

95 changes: 95 additions & 0 deletions .github/workflows/pin-watch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
name: Pin watch

# Self-CI for this repository: opens a single issue when any pinned tool
# version here has drifted from its upstream release. Glyndor/podup#1526
# motivated this — the reusables each carry their own pins, and the
# hand survey on 2026-08-24 found eight of nineteen drifted, one of
# them a real defect. A hand survey is exactly what the issue says is
# not good enough.
#
# The Python script lives at `scripts/pin-watch.py` rather than as a
# heredoc inside this file, mirroring how `pin-policy-reusable.yml`
# invokes `scripts/pin-policy.py`. A heredoc here would force every
# `actionlint` run on this workflow through shellcheck against the full
# script, and the script's size (well over a hundred lines) hits a
# pathological case in shellcheck v0.11.0 that hangs the linter
# indefinitely. The separate-file form is also the more reviewable
# shape: pin-watch.py can be diffed and tested like any other Python
# module, and this workflow file stays focused on the schedule, the
# permissions and the issue it opens.
#
# Pin values are READ FROM the workflow files at runtime, never
# hardcoded. Hardcoding the pin in the watcher would mean the watcher
# can disagree with reality, which is the bug it exists to prevent.
# Where a pin appears in more than one file (rust toolchain,
# actionlint, shellcheck), the first file listed in scripts/pin-watch.py
# is the canonical source — every other file is asserted equal to it
# by tests/test_workflow_pins.py, so the watcher reads one and trusts
# the test to enforce the rest.
#
# A held pin (the four entries in HOLDS in scripts/pin-watch.py) is
# reported ONLY when the pinned value stops matching its hold version —
# meaning somebody changed the pin and the hold note is now stale. While
# the pin still matches the hold, the watcher is silent about it.
# Reporting the upstream delta every Tuesday would train the reader to
# ignore the issue, which is the failure mode the hold list exists to
# prevent. Do not "fix" the silence by deleting the entry.
#
# Schedule: Tuesday 06:00 UTC. Deliberately not Monday: podup's own
# pin-watch runs Monday 05:00, and stacking this repository's other
# scheduled work on a single minute is the failure mode
# schedule-freshness.yml exists to detect (see 2026-06-29 in the header
# of that reusable).
#
# Reporting shape, after podup's pin-watch: collect all drifts, open
# ONE issue titled exactly `Pinned tool versions have drifted`, skip if
# an issue with that exact title is already open. Labels: `type:ci`,
# `prio:P2`, `status:ready`, `area:ci`, `effort:S`. Exit 0 with a short
# confirmation when nothing drifted.
#
# PSScriptAnalyzer's upstream endpoint
# (powershellgallery.com/api/v2/FindPackagesById()) returns an Atom XML
# feed and is awkward to parse reliably; pssa-version is therefore read
# (so the pin is still reviewed) but its upstream is not queried, and
# the entry sits in SKIP_UPSTREAM in scripts/pin-watch.py. If a future
# maintainer wires a cleaner endpoint, drop the skip and add a fetcher.
#
# Default shell is pinned to bash: the inner `sort -V` style
# comparators the upstream fetchers use are GNU semantics, and a future
# Windows caller would otherwise silently mis-compare and fail closed
# on an empty string.

on:
schedule:
- cron: '0 6 * * 2'
workflow_dispatch:

permissions:
contents: read
issues: write

defaults:
run:
shell: bash

concurrency:
group: pin-watch-${{ github.ref }}
cancel-in-progress: true

jobs:
pin-watch:
name: pin watch
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Detect drift and open a tracking issue
env:
GH_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
run: |
set -euo pipefail
python3 -u scripts/pin-watch.py
13 changes: 7 additions & 6 deletions .github/workflows/rust-supply-chain.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ on:
# Pinned, not the runner's floating preinstalled Rust — see rust-ci.yml's
# toolchain input for why an unpinned toolchain is a problem.
#
# Keep this equal to rust-ci.yml's `toolchain`. It was 1.97 while rust-ci
# was already on 1.98, because the bump raised one and not the other and
# nothing compared them. A repository whose SBOM is produced by a compiler
# its test suite never ran is the defect podup#1487 recorded, and podup
# now has a test asserting its own two pins agree — nothing asserts it
# across these two reusables, so it is written here instead.
# Keep this equal to rust-ci.yml's and rust-audit.yml's `toolchain`. It
# was 1.97 while rust-ci was already on 1.98, because the bump raised
# one and not the other and nothing compared them. A repository whose
# SBOM is produced by a compiler its test suite never ran is the defect
# Glyndor/podup#1487 recorded. tests/test_workflow_pins.py asserts the
# three defaults agree; keep them in step on the bump PR so the test
# stays green.
toolchain:
description: Rust toolchain to pin the SBOM and license job to
type: string
Expand Down
11 changes: 11 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Test dependencies for this repository's own suite.
#
# python-ci installs this file when it exists, which is how tests/ gets PyYAML.
# tests/test_workflow_pins.py parses the reusables as YAML rather than by regex,
# because the values it compares are quoted inconsistently across the files and a
# regex that tolerates every form is harder to trust than a parser.
#
# This is a hand-typed pin like the nineteen in the workflows, so pin-watch
# watches it too — the alternative is a watcher that misses the pin its own
# repository added.
pyyaml==6.0.3
Loading
Loading