1717# any package drifts. Owner decides what to do with the report.
1818
1919name : Package Drift Detection
20-
2120on :
2221 schedule :
23- - cron : ' 17 6 * * 1' # Mondays 06:17 UTC — off-peak, weekly cadence
22+ - cron : ' 17 6 * * 1' # Mondays 06:17 UTC — off-peak, weekly cadence
2423 workflow_dispatch :
2524 pull_request :
2625 paths :
2726 - ' packages/**'
2827 - ' .github/workflows/package-drift.yml'
29-
3028concurrency :
3129 group : ${{ github.workflow }}-${{ github.ref }}
3230 cancel-in-progress : true
33-
3431permissions :
3532 contents : read
36-
3733jobs :
3834 detect-drift :
3935 runs-on : ubuntu-latest
@@ -43,89 +39,11 @@ jobs:
4339 uses : actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
4440 with :
4541 path : ecosystem
46-
4742 - name : Compare packages/* against standalone repos
4843 id : drift
4944 env :
5045 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-
46+ run: "set -u\ncd \"$GITHUB_WORKSPACE/ecosystem\"\n\nsummary=\"$GITHUB_STEP_SUMMARY\"\ndrift_count=0\nidentical_count=0\nmissing_remote=0\n\n{\n echo \"# Package Drift Detection\"\n echo\n echo \"Comparing \\`packages/*/\\` against \\`github.com/${GH_OWNER}/<Pkg>.jl\\` HEAD.\"\n echo \"Only package-essentials are compared (\\`src/\\`, \\`test/runtests.jl\\`, \\`Project.toml\\`).\"\n echo \"Scaffolding differences (\\`flake.nix\\`, governance docs, \\`benches/\\`, etc.) are intentional and ignored.\"\n echo\n echo \"| Package | Status | Differing essentials |\"\n echo \"|---|---|---|\"\n} >> \"$summary\"\n\ntmpdir=$(mktemp -d)\ntrap 'rm -rf \"$tmpdir\"' EXIT\n\nfor pkgdir in packages/*/; do\n pkg=$(basename \"$pkgdir\")\n name=\"${pkg%.jl}\"\n standalone=\"https://github.com/${GH_OWNER}/${pkg}.git\"\n clone=\"$tmpdir/$pkg\"\n\n if ! git clone --depth 1 --quiet \"$standalone\" \"$clone\" 2>/dev/null; then\n missing_remote=$((missing_remote + 1))\n echo \"| \\`${name}\\` | ⚠️ remote unreachable | (skipped) |\" >> \"$summary\"\n continue\n fi\n\n differing=()\n for rel in \"src\" \"test/runtests.jl\" \"Project.toml\"; do\n eco=\"$pkgdir$rel\"\n lib=\"$clone/$rel\"\n if [ -e \"$eco\" ] || [ -e \"$lib\" ]; then\n if ! diff -rq \"$eco\" \"$lib\" >/dev/null 2>&1; then\n differing+=(\"$rel\")\n fi\n fi\n done\n\n if [ ${#differing[@]} -eq 0 ]; then\n identical_count=$((identical_count + 1))\n echo \"| \\`${name}\\` | ✅ identical (essentials) | — |\" >> \"$summary\"\n else\n drift_count=$((drift_count + 1))\n joined=$(IFS=', '; echo \"${differing[*]}\")\n echo \"| \\`${name}\\` | \U0001F536 drift | $joined |\" >> \"$summary\"\n fi\ndone\n\n{\n echo\n echo \"## Totals\"\n echo\n echo \"- **Drift**: $drift_count\"\n echo \"- **Identical (essentials)**: $identical_count\"\n echo \"- **Remote unreachable**: $missing_remote\"\n echo\n echo \"## What to do with this\"\n echo\n 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:\"\n echo\n echo \"- If the standalone is canonical → sync standalone → monorepo by replacing the vendored copy.\"\n echo \"- If the monorepo is canonical → push the changed file back to the standalone repo.\"\n echo\n 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.\"\n} >> \"$summary\"\n\necho \"drift_count=$drift_count\" >> \"$GITHUB_OUTPUT\"\necho \"identical_count=$identical_count\" >> \"$GITHUB_OUTPUT\"\necho \"missing_remote=$missing_remote\" >> \"$GITHUB_OUTPUT\"\n"
12947 - name : Annotate drift
13048 if : steps.drift.outputs.drift_count != '0'
13149 run : |
0 commit comments