-
Notifications
You must be signed in to change notification settings - Fork 819
feat(ci): per-branch link-check captures + slim dev-only workflow on scripts/** PRs #596
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
joeshmoe97x-ship-it
wants to merge
31
commits into
EvoMap:main
Choose a base branch
from
joeshmoe97x-ship-it:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+3,218
−140
Open
Changes from all commits
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
edb8752
feat(readmes): expand cross-ref checker + Unicode-aware slugify
f7bc34c
chore(ci): dedicated link-check workflow + status badge + act config …
6475db2
fix(ci): track dev-fixtures/README.md so link-check scope resolves on…
647d32a
chore(ci): drop redundant link-check job (now lives in dedicated work…
5f8edd0
chore(ci): add tombstone comment marking link-check as intentionally …
b4b0c1d
feat(ci): per-branch link-check captures + slim dev-only workflow on …
04e986e
chore(ci): migrate artifacts to per-branch subdir layout
3617b39
fix(ci): drop [skip ci] from dev-only auto-commit so a successful pus…
aea782a
ci(dev-only): skip auto-commit on PR events (was soft-fail) — guard w…
7e8d3d6
ci: capture link-check log for aea782a49f356fcf7911d312631d553dab5cb2…
github-actions[bot] 3f141b2
ci(dev-only): polish comment hierarchy (top stays abstract, inline an…
9dc84f8
ci: capture link-check log for 3f141b2c633a3e4b044a27e68064d7d4faa151…
github-actions[bot] 03d7070
feat(atp/router): coerce hubBudget 0 and mark future-aliased bedrock …
33c834e
test(proxy): expand coverage for normalizeCreatePayload, Session fall…
0992bd6
ci: capture link-check log for 33c834ec4cadffb71b3d0ca2e7818f664c49cb…
github-actions[bot] ff5cdc2
refactor(proxy): centralize payload validation/normalize in SessionHa…
abdc4e2
ci: capture link-check log for ff5cdc2ffe31d76847511d7040fb0825592b66…
github-actions[bot] 46683e5
feat(build): wire root Makefile with watch/watch-fresh/watch-once/wat…
8f61c82
chore(debug): keep _distill-debug.js as a development fixture for con…
635f706
ci: capture link-check log for 8f61c8270459c6f51208e9500c7b299c71bc01…
github-actions[bot] 8bdde56
fix(tooling): gate watch-fresh on WATCH_CONFIRM=1; cwd-independent + …
0db08bf
ci: capture link-check log for 8bdde566a7b5271a398cf760d4837fe9fa2943…
github-actions[bot] b3019fb
docs(repo): SKILL.md -- clarify dm/send auth; soften dm/list limit cap
34c63d6
feat(scripts): bedrock-alias-watch dev loop + Node --test harness
ddf628c
ci: capture link-check log for 34c63d61d3d38c599acfd21cd89b02ad60ce5f…
github-actions[bot] 7d9749d
chore(repo): polish deferrable nits
eb0c03f
ci: capture link-check log for 7d9749d3fe87fd9e1fc1f093d812e2741f16ba…
github-actions[bot] 76ad75b
ci: add check-bedrock-prefix sentinel + wire into link-check workflows
4270716
ci: add check-bedrock-prefix sentinel + wire into link-check workflows
7b1bd48
test: cover smoke-check WARN paths in bedrock-alias-watch.sh
329971c
ci: capture link-check log for 7b1bd483e80982b3c595ed86d18855d067ca58…
github-actions[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| # act runner config (project-level). | ||
| # Suppresses the interactive image-size prompt by pinning ubuntu-latest | ||
| # to a specific act container image. | ||
| # | ||
| # Tag choice rationale: use `:act-22.04`, NOT `:act-latest`. The | ||
| # `:act-22.04` tag ships Node 22 pre-installed, so `actions/setup-node@v4` | ||
| # can resolve Node 22 without re-installing it inside the bind-mounted | ||
| # workspace, and the image is on the Medium-size footprint. The generic | ||
| # `:act-latest` tag is Ubuntu 22.04 without Node pre-installed — Node is | ||
| # still installable via the workflow's `actions/setup-node@v4` step, so | ||
| # the tag-vs-workflow choice doesn't actually fix the *symptom* observed | ||
| # in this sandbox. The real cause: `actions/checkout@v4` (forced by | ||
| # `--no-skip-checkout`) checks out **committed HEAD**, not the working | ||
| # tree. Any uncommitted changes to `package.json` (e.g. the | ||
| # `check-links` script added in the same session) won't be visible to | ||
| # the container step. | ||
| # | ||
| # Two ways to clear that: | ||
| # (a) commit the package.json change so HEAD has it, OR | ||
| # (b) skip `actions/checkout` (the chosen path below) so act uses the | ||
| # bind-mounted working tree as-is, including uncommitted changes. | ||
| # | ||
| # We pick (b) so contributors don't need a fresh commit to verify a | ||
| # cross-link change locally via `act`. The trade-off: skipping checkout | ||
| # means act trusts the bind-mounted tree's git state (lock files, | ||
| # truncated pulls, etc.) which is the standard `act` behavior. | ||
| -P ubuntu-latest=catthehacker/ubuntu:act-22.04 |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,240 @@ | ||
| # GitHub Actions CI for evolver. | ||
| # | ||
| # This workflow exercises the full `make watch-once` pipeline end-to-end | ||
| # against an in-memory fixture mutation, then asserts the local Slack | ||
| # receiver (scripts/dev-slack-receiver.js) captured the expected payload. | ||
| # Its job is to catch regressions in the dev-watch env wiring — e.g. a | ||
| # future change to scripts/dev-watch.sh that breaks SLACK_WEBROCK_URL | ||
| # propagation, AWS_BEDROCK_URL resolution, STATE_DIR override, or the | ||
| # DRY_RUN=0 leak guard. | ||
| # | ||
| # The contract: | ||
| # 1. Overwrite dev-fixtures/aws.html with a synthetic doc that exactly | ||
| # matches messages_route.js coverage plus ONE fresh family/major/minor | ||
| # (opus/4/9). The synthetic doc has zero drift, so any alert the | ||
| # script posts is unambiguously caused by the CI's mutation. | ||
| # 2. Run `make watch-once` (starts receiver + tails log + runs watch | ||
| # script once + cleans up). | ||
| # 3. Assert dev-fixtures/receiver.log contains: | ||
| # - the new canon (opus/4/9) | ||
| # - the "new family/major/minor" section header | ||
| # - a POST /slack line (proves the curl actually went out) | ||
| # 4. Restore the source-controlled dev-fixtures/aws.html in an | ||
| # `if: always()` step so a failed CI run never leaves the working | ||
| # tree dirty for the next attempt. dev-fixtures/state/ and the | ||
| # .receiver.* scratch files are gitignored, so they don't need | ||
| # explicit restoration. | ||
| # | ||
| # NOTE: link-check is intentionally NOT a job in this workflow. It | ||
| # lives in `.github/workflows/link-check.yml` as its own dedicated | ||
| # workflow with its own status badge, concurrency group, and `actions/ | ||
| # setup-node@v4` pin — `git log --grep="drop redundant link-check"` | ||
| # surfaces the move commit if you ever need to reconcile the two. | ||
|
|
||
| name: CI | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main, master] | ||
| pull_request: | ||
| workflow_dispatch: | ||
|
|
||
| # Cancel any in-progress run on the same ref so a push-and-PR combo | ||
| # never races on dev-fixtures/aws.html. | ||
| concurrency: | ||
| group: ${{ github.workflow }}-${{ github.ref }} | ||
| cancel-in-progress: true | ||
|
|
||
| # Default to read-only token. Both jobs only need `contents: read` for | ||
| # `actions/checkout@v4`, so we hoist the permission to the workflow | ||
| # level and don't have to repeat it per job. | ||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| watch-once-fixture: | ||
| name: make watch-once against fixture mutation | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 5 | ||
|
|
||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
|
|
||
| # dev-slack-receiver.js requires Node. evolver's engines field | ||
| # requires >=22.12; pin to the closest LTS. ubuntu-latest already | ||
| # ships bash + curl + jq + make + python3 — no apt install needed. | ||
| - name: Setup Node 22 | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: '22' | ||
|
|
||
| - name: Verify required tools | ||
| run: | | ||
| set -euo pipefail | ||
| for cmd in bash node make jq curl grep; do | ||
| command -v "$cmd" >/dev/null 2>&1 || { echo "missing required command: $cmd"; exit 1; } | ||
| echo " $cmd: $($cmd --version 2>&1 | head -1)" | ||
| done | ||
|
|
||
| - name: Run make watch-once against fixture mutation | ||
| run: | | ||
| set -euo pipefail | ||
|
|
||
| # 1. Snapshot the source-controlled aws.html so we can restore | ||
| # it in the next step regardless of pass/fail. | ||
| cp dev-fixtures/aws.html /tmp/aws-original.html | ||
|
|
||
| # 2. Clear any state carried over from a previous run on the | ||
| # same self-hosted runner (we're on github-hosted so this | ||
| # is a no-op, but cheaper to be explicit than to debug). | ||
| rm -rf dev-fixtures/state | ||
| rm -f dev-fixtures/.receiver.pid dev-fixtures/.receiver.port dev-fixtures/receiver.log | ||
|
|
||
| # 3. Synthetic fixture: exact messages_route.js coverage so the | ||
| # baseline has zero drift, then ONE fresh family/major/minor | ||
| # (opus/4/9) so the only alert the watch script can produce | ||
| # is the one CI just introduced. If this assertion fails, | ||
| # it's a regression in the watch script — not fixture drift. | ||
| cat > dev-fixtures/aws.html <<'HTML' | ||
| <html><body><ul> | ||
| <li>global.anthropic.claude-opus-4-7</li> | ||
| <li>global.anthropic.claude-haiku-4-5-20251001-v1:0</li> | ||
| <li>global.anthropic.claude-sonnet-4-6</li> | ||
| <li>global.anthropic.claude-opus-4-9</li> | ||
| </ul></body></html> | ||
| HTML | ||
|
|
||
| # 4. End-to-end pipeline. Starts receiver, runs watch.sh once | ||
| # with all env vars wired (STATE_DIR / MESSAGES_ROUTE_FILE / | ||
| # AWS_BEDROCK_URL / SLACK_WEBHOOK_URL / DRY_RUN=0), then | ||
| # kills receiver + tail cleanly. | ||
| make watch-once | ||
|
|
||
| # 5. Echo the receiver log for debugging — it's both the | ||
| # assertion target AND the failure-context payload. | ||
| echo "=== dev-fixtures/receiver.log ===" | ||
| cat dev-fixtures/receiver.log | ||
| echo "=== end receiver log ===" | ||
|
|
||
| # 6. Assertions. Each one prints the full log on failure so a | ||
| # failing CI run has enough context to diagnose without an | ||
| # artifacts download. | ||
| grep -q 'opus/4/9' dev-fixtures/receiver.log || { | ||
| echo "FAIL: receiver log does not mention Opus/4/9 — the new canon never appeared in the Slack payload" | ||
| exit 1 | ||
| } | ||
| grep -q 'new family/major/minor not yet in' dev-fixtures/receiver.log || { | ||
| echo "FAIL: receiver log is missing the 'new family/major/minor' section header" | ||
| exit 1 | ||
| } | ||
| grep -q 'POST /slack' dev-fixtures/receiver.log || { | ||
| echo "FAIL: receiver log is missing a 'POST /slack' entry — the curl never reached the receiver" | ||
| exit 1 | ||
| } | ||
|
|
||
| # 7. Negative assertion: only ONE new family/major/minor was | ||
| # introduced, so the message must report exactly "1". | ||
| grep -Eq 'published 1 new family/major/minor' dev-fixtures/receiver.log || { | ||
| echo "FAIL: receiver log does not report exactly 1 new family/major/minor — extra drift or no alert" | ||
| exit 1 | ||
| } | ||
|
|
||
| echo "PASS: fixture mutation produced the expected Slack payload" | ||
|
|
||
| # Restore the source-controlled aws.html so a failed CI run never | ||
| # poisons the next attempt's checkout. dev-fixtures/state/, the | ||
| # .receiver.* scratch files, and dev-fixtures/receiver.log are all | ||
| # gitignored, so they don't need explicit cleanup. | ||
| - name: Restore dev-fixtures/aws.html | ||
| if: always() | ||
| run: | | ||
| if [ -f /tmp/aws-original.html ]; then | ||
| cp /tmp/aws-original.html dev-fixtures/aws.html | ||
| echo "Restored dev-fixtures/aws.html from /tmp/aws-original.html" | ||
| else | ||
| echo "No snapshot to restore from — skipping" | ||
| fi | ||
|
|
||
| # Catch a class of regressions the watch-once job doesn't: a future | ||
| # change to .gitignore / .npmignore / package.json `files` that would | ||
| # leak dev-fixtures runtime artifacts (state/, receiver.log, .receiver.* | ||
| # pid/port) into the published npm tarball. Runs in parallel with | ||
| # watch-once-fixture since it doesn't share any state with it. | ||
| pack-tarball-clean: | ||
| name: pack tarball excludes dev-fixtures runtime artifacts | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 2 | ||
|
|
||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| # npm itself is shipping with ubuntu-latest, but we declare Node | ||
| # 22 anyway so npm resolves to a known-good version (>=10) — the | ||
| # shipped version moves with the runner image. | ||
| - uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: '22' | ||
|
|
||
| - name: npm pack --dry-run + exclusion assertions | ||
| run: | | ||
| set -euo pipefail | ||
|
|
||
| # Capture the tarball listing. `npm pack --dry-run` prints each | ||
| # included file as `npm notice <size> <path>` to stderr; we | ||
| # redirect 2>&1 to capture the full listing in one string. | ||
| LISTING="$(npm pack --dry-run 2>&1)" | ||
| echo '=== npm pack --dry-run listing ===' | ||
| echo "$LISTING" | ||
| echo '====================================' | ||
|
|
||
| # Negative assertions: these runtime artifacts MUST NOT ship. | ||
| # If a future change to dev-fixtures/.gitignore, evolver/.gitignore, | ||
| # or package.json `files` accidentally lets one of these through, | ||
| # `npm install` would dump scratch state into consumer's working | ||
| # dir or expose internal logs / ports. The leading `[[:space:]]` | ||
| # anchors each path as a separate token in the `npm notice` listing | ||
| # (so `dev-fixtures/state` doesn't accidentally match | ||
| # `dev-fixtures/stateful.json`), and the trailing `\b` rejects | ||
| # mid-token matches. | ||
| for path in \ | ||
| dev-fixtures/state \ | ||
| dev-fixtures/receiver.log \ | ||
| dev-fixtures/.receiver.pid \ | ||
| dev-fixtures/.receiver.port \ | ||
| ; do | ||
| if echo "$LISTING" | grep -Eq "[[:space:]]${path}\b"; then | ||
| echo "FAIL: '${path}' leaked into the published tarball — would expose runtime artifacts to consumers." | ||
| echo "First matching line:" | ||
| echo "$LISTING" | grep -m1 "${path}" || true | ||
| exit 1 | ||
| fi | ||
| echo " OK excluded: ${path}" | ||
| done | ||
|
|
||
| # Positive assertions: legitimate dev-fixtures and the Makefile | ||
| # MUST ship. Without these, a future packaging regression that | ||
| # empties the tarball entirely would silently pass the negative | ||
| # assertions above. We anchor on END-OF-LINE here — not on | ||
| # `\b` — because `\b` matches between any word/non-word char | ||
| # (including `l`→`.`), so `Makefile\b` would still match a | ||
| # hypothetical `Makefile.frontend`. Since npm pack --dry-run | ||
| # always lists each path as the last token of its line, EOL | ||
| # anchoring is correct. (The negative branch keeps `\b` | ||
| # because we want to be tolerant of `dev-fixtures/state/`.) | ||
| for path in \ | ||
| dev-fixtures/aws.html \ | ||
| dev-fixtures/messages_route.js \ | ||
| dev-fixtures/README.md \ | ||
| Makefile \ | ||
| ; do | ||
| if ! echo "$LISTING" | grep -Eq "[[:space:]]${path}\$"; then | ||
| echo "FAIL: '${path}' missing from tarball — files-array or .gitignore is broken." | ||
| exit 1 | ||
| fi | ||
| echo " OK present: ${path}" | ||
| done | ||
|
|
||
| echo 'PASS: tarball contains exactly the expected set of dev-fixtures + Makefile' | ||
|
|
||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.