Skip to content

Commit b630040

Browse files
ci(drift): detect package-essentials drift vs standalone repos (#9)
* chore(fixtures): delete stale SafeDOMExample.res ReScript fixture (Refs gitbot-fleet#148, #208; affinescript#229) Removes 11 copies of the stale SafeDOMExample.res ReScript fixture from this repo. One of 1,267 byte-clustered copies across the estate (129 repos). ReScript is fully banned in new code (2026-04-30 policy refresh). Current-grammar AffineScript replacement lives at gitbot-fleet/bots/*/examples/SafeDOMExample.affine (PR gitbot-fleet#210 MERGED). The example fixtures are not load-bearing — propagated from an earlier template-instantiation script. Refs hyperpolymath/gitbot-fleet#148, #208 Refs hyperpolymath/affinescript#57, #229 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ci(drift): detect package-essentials drift vs standalone repos Adds a report-only weekly workflow comparing every packages/*/ against its standalone counterpart at github.com/hyperpolymath/<Pkg>.jl. Only package-essentials (src/, test/runtests.jl, Project.toml) are compared — scaffolding differences (flake.nix, governance docs, benches/, etc.) are intentional under the dual-shape arrangement audited 2026-05-27 and correctly ignored. Behaviour: never fails the build, never auto-fixes, never picks a canonical side. Drift is surfaced via: - GitHub Step Summary (always-visible markdown table per package) - workflow notice annotation (only if drift_count > 0) Triggers: weekly cron (Mon 06:17 UTC, off-peak), workflow_dispatch, and pull_request on packages/** or this workflow file. SHA-pinned actions/checkout@v4 matches existing julia-ecosystem conventions (casket-pages.yml, governance.yml). Concurrency guard + contents:read baseline match the same. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent b5f9bc7 commit b630040

1 file changed

Lines changed: 132 additions & 0 deletions

File tree

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# SPDX-License-Identifier: MPL-2.0
2+
# package-drift.yml — detect drift between vendored packages under
3+
# packages/*/ and their standalone counterparts at
4+
# github.com/hyperpolymath/<PackageName>.jl.
5+
#
6+
# The estate intentionally maintains both shapes (see julia-libraries
7+
# vs julia-ecosystem audit, 2026-05-27): standalone repos carry the
8+
# full scaffolding (CI, governance, contractiles, flake.nix, docs);
9+
# the monorepo carries package-essentials only. This workflow compares
10+
# *just* the package-essentials (src/, test/runtests.jl, Project.toml)
11+
# so scaffolding differences are correctly ignored and only meaningful
12+
# code drift is reported.
13+
#
14+
# Behaviour: report-only. Never fails the build, never auto-fixes,
15+
# never picks a canonical side. Drift summary is written to the GitHub
16+
# Step Summary (always visible on a run); an annotation is emitted if
17+
# any package drifts. Owner decides what to do with the report.
18+
19+
name: Package Drift Detection
20+
21+
on:
22+
schedule:
23+
- cron: '17 6 * * 1' # Mondays 06:17 UTC — off-peak, weekly cadence
24+
workflow_dispatch:
25+
pull_request:
26+
paths:
27+
- 'packages/**'
28+
- '.github/workflows/package-drift.yml'
29+
30+
concurrency:
31+
group: ${{ github.workflow }}-${{ github.ref }}
32+
cancel-in-progress: true
33+
34+
permissions:
35+
contents: read
36+
37+
jobs:
38+
detect-drift:
39+
runs-on: ubuntu-latest
40+
timeout-minutes: 15
41+
steps:
42+
- name: Checkout ecosystem
43+
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
44+
with:
45+
path: ecosystem
46+
47+
- name: Compare packages/* against standalone repos
48+
id: drift
49+
env:
50+
GH_OWNER: hyperpolymath
51+
run: |
52+
set -u
53+
cd "$GITHUB_WORKSPACE/ecosystem"
54+
55+
summary="$GITHUB_STEP_SUMMARY"
56+
drift_count=0
57+
identical_count=0
58+
missing_remote=0
59+
60+
{
61+
echo "# Package Drift Detection"
62+
echo
63+
echo "Comparing \`packages/*/\` against \`github.com/${GH_OWNER}/<Pkg>.jl\` HEAD."
64+
echo "Only package-essentials are compared (\`src/\`, \`test/runtests.jl\`, \`Project.toml\`)."
65+
echo "Scaffolding differences (\`flake.nix\`, governance docs, \`benches/\`, etc.) are intentional and ignored."
66+
echo
67+
echo "| Package | Status | Differing essentials |"
68+
echo "|---|---|---|"
69+
} >> "$summary"
70+
71+
tmpdir=$(mktemp -d)
72+
trap 'rm -rf "$tmpdir"' EXIT
73+
74+
for pkgdir in packages/*/; do
75+
pkg=$(basename "$pkgdir")
76+
name="${pkg%.jl}"
77+
standalone="https://github.com/${GH_OWNER}/${pkg}.git"
78+
clone="$tmpdir/$pkg"
79+
80+
if ! git clone --depth 1 --quiet "$standalone" "$clone" 2>/dev/null; then
81+
missing_remote=$((missing_remote + 1))
82+
echo "| \`${name}\` | ⚠️ remote unreachable | (skipped) |" >> "$summary"
83+
continue
84+
fi
85+
86+
differing=()
87+
for rel in "src" "test/runtests.jl" "Project.toml"; do
88+
eco="$pkgdir$rel"
89+
lib="$clone/$rel"
90+
if [ -e "$eco" ] || [ -e "$lib" ]; then
91+
if ! diff -rq "$eco" "$lib" >/dev/null 2>&1; then
92+
differing+=("$rel")
93+
fi
94+
fi
95+
done
96+
97+
if [ ${#differing[@]} -eq 0 ]; then
98+
identical_count=$((identical_count + 1))
99+
echo "| \`${name}\` | ✅ identical (essentials) | — |" >> "$summary"
100+
else
101+
drift_count=$((drift_count + 1))
102+
joined=$(IFS=', '; echo "${differing[*]}")
103+
echo "| \`${name}\` | 🔶 drift | $joined |" >> "$summary"
104+
fi
105+
done
106+
107+
{
108+
echo
109+
echo "## Totals"
110+
echo
111+
echo "- **Drift**: $drift_count"
112+
echo "- **Identical (essentials)**: $identical_count"
113+
echo "- **Remote unreachable**: $missing_remote"
114+
echo
115+
echo "## What to do with this"
116+
echo
117+
echo "Drift in package-essentials means \`src/\`, \`test/runtests.jl\`, or \`Project.toml\` diverged between this monorepo's vendored copy and the standalone repo. Pick the canonical side per package and reconcile:"
118+
echo
119+
echo "- If the standalone is canonical → sync standalone → monorepo by replacing the vendored copy."
120+
echo "- If the monorepo is canonical → push the changed file back to the standalone repo."
121+
echo
122+
echo "This workflow does **not** auto-fix or open PRs; it only reports. See the [2026-05-27 drift audit](https://github.com/hyperpolymath/julia-ecosystem) for context."
123+
} >> "$summary"
124+
125+
echo "drift_count=$drift_count" >> "$GITHUB_OUTPUT"
126+
echo "identical_count=$identical_count" >> "$GITHUB_OUTPUT"
127+
echo "missing_remote=$missing_remote" >> "$GITHUB_OUTPUT"
128+
129+
- name: Annotate drift
130+
if: steps.drift.outputs.drift_count != '0'
131+
run: |
132+
echo "::notice title=Package drift detected::${{ steps.drift.outputs.drift_count }} package(s) have drift in essentials. See the Job Summary for the per-package table."

0 commit comments

Comments
 (0)