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
10 changes: 5 additions & 5 deletions .github/workflows/archify.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
name: archify
# Opens a PR when tt-a1i/archify cuts a release newer than vendor/archify.lock.json. docs/archify.md.
# Pushes branch archify/<tag> when tt-a1i/archify cuts a release newer than vendor/archify.lock.json, then stops: GitHub Actions
# may not open pull requests in this repository, so the run leaves a notice and a person opens the PR. docs/archify.md.
on:
schedule:
- cron: '0 14 * * 1'
workflow_dispatch:
permissions:
contents: write
pull-requests: write
jobs:
bump:
runs-on: ubuntu-latest
Expand All @@ -21,11 +21,11 @@ jobs:
else echo "tag=$(curl -fsSL -H "Authorization: Bearer $GITHUB_TOKEN" https://api.github.com/repos/tt-a1i/archify/releases/latest | jq -r .tag_name)" >> "$GITHUB_OUTPUT"; fi
- if: steps.check.outputs.tag != ''
env:
GH_TOKEN: '${{ github.token }}'
GITHUB_TOKEN: '${{ github.token }}'
TAG: '${{ steps.check.outputs.tag }}'
run: |
git ls-remote --exit-code origin "refs/heads/archify/$TAG" && { echo "archify/$TAG already open"; exit 0; }
PR="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/compare/main...archify/$TAG?expand=1"
git ls-remote --exit-code origin "refs/heads/archify/$TAG" && { echo "::notice title=archify $TAG::Branch archify/$TAG is pushed and not merged yet. Open the PR by hand: $PR"; exit 0; }
node bin/archify-sync.mjs --tag "$TAG"
node --test test/archify.test.mjs
git config user.name 'github-actions[bot]'
Expand All @@ -34,4 +34,4 @@ jobs:
git add vendor CHANGELOG.md docs/archify.md
git commit -m "archify: vendor $TAG"
git push origin "archify/$TAG"
gh pr create --title "archify: vendor $TAG" --body "Moves vendor/archify to $TAG with bin/archify-sync.mjs. Release notes: https://github.com/tt-a1i/archify/releases/tag/$TAG. The archify gate passed in this run; close and reopen the PR to start the full test workflow."
echo "::notice title=archify $TAG::Pushed branch archify/$TAG; the archify gate passed in this run. Open the PR by hand: $PR"
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Changelog
## Unreleased
- **The archify workflow stops at the pushed branch.** The scheduled run on 2026-09-28 vendored archify v3.0.0, pushed `archify/v3.0.0` and then failed at `gh pr create`: GitHub Actions may not open pull requests in this repository. The workflow now pushes the branch, leaves a notice that links the compare page and exits 0. It repeats the notice each week until the branch is merged, and it no longer asks for the `pull-requests` permission. `docs/archify.md` says to open the PR by hand.
- **Chart bars are square at both ends (#162).** The engine painted every `bar` row with `border-radius:6px 6px 0 0`, so a column was rounded on its value end and an `hbar` bar on its top corners, and each read as a tab. `template.html` now paints no radius on a bar: every chart form (`bar`, `hbar`, a `compare` series, the template bars) is square by default, and a row that sets `radius` rounds all four corners. SKILL.md's row table and `docs/charts.md` say so. Deck and library html rebuilt. Gates: test/chart.test.mjs asserts that the chart rows and every template's rows carry no one-sided radius, and renders the chart forms and the chart templates in Chromium to check that each bar is square and that no mark draws a one-sided radius.
- **Undo and Delete buttons in the HUD.** Undo (⌘Z) and delete (⌫) were keys only, so a phone could neither take back an edit nor remove a row or a slide (#167). The edit group now carries an Undo button (Lucide `undo-2`) and a Delete button (Lucide `trash-2`) on every pointer, after duplicate. Each runs the code its key runs in the same place: the browser's text undo and delete while a row is being edited, `sheetKey()` in the contact sheet, `undo()` and the new `delSel()` (the canvas key's own body, moved into a function both share) on the canvas. Undo is disabled while the undo stack is empty; Delete is disabled with no selection on the canvas, and in the sheet with no selection or one slide left. Neither appears in the present-mode pill. The HUD manifest in `docs/editor.md` gains `undobtn` and `delbtn`. Guarded by `test/hud.test.mjs` and a tap-only test in `test/touch.test.mjs`.
- **A served deck spellchecks the words you type.** Issue 86: spellcheck ran at build time only, so a word typed after `create` never reached the badge, the wash, the thumbnail counts or the panel, and the underline seen while typing was the browser's own, gone once the caret left the row. `bin/serve.mjs` now answers `POST /__decklet/spell` with the refused words of one row and their suggestions, through `lib/spell.mjs` with the build's dictionary and the deck's `spell.ignore`; it takes the token and Host guards of the write endpoints and at most 500 words of 64 characters, and answers 503 when the dictionary is not installed. The editor probes the endpoint, sends a row's words when its edit commits (debounced), and merges the answer into the set it already paints. Each PUT rewrites the file's `SPELL` block from the saved model (`splice()` takes it as a fourth argument), so a reload shows the live flags. A deck from disk, from another host, or from a server without a dictionary keeps build-time checking, and the spellcheck button's tip says so. Tests: `test/serve.test.mjs` (endpoint, guards, the SPELL block on PUT, no dictionary), `test/serve-live.test.mjs` (type, commit, badge, wash, panel with suggestions, thumbnail, reload, fix, in every browser project), `test/spell.test.mjs` (a `file://` deck makes no request and shows the tip).
Expand Down
2 changes: 1 addition & 1 deletion docs/archify.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ node bin/archify-sync.mjs --check # exit 1 when a newer release is out

The script replaces the tree, rewrites the lock, adds a line under `## Unreleased` in CHANGELOG.md and updates the tag in this page. Review the upstream release notes, run `npm test`, and ship it as its own PR.

The `archify` workflow runs `--check` every Monday. On a newer upstream release it runs the sync, runs the archify gate and opens a PR on branch `archify/<tag>`. A PR opened by the workflow's token starts no other workflow, so close and reopen it to run the full `test` gate before merging.
The `archify` workflow runs `--check` every Monday. On a newer upstream release it runs the sync, runs the archify gate, pushes branch `archify/<tag>` and stops with a notice on the run that links the compare page. GitHub Actions may not open pull requests in this repository, so open the PR by hand from that branch; the `test` gate starts on its own. Each later run repeats the notice until the branch is merged.
11 changes: 11 additions & 0 deletions test/archify.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,14 @@ test('the pin is documented where a reader looks', () => {
assert.match(read('docs/figures.md'), /\(archify\.md\)/, 'docs/figures.md must link docs/archify.md');
assert.ok(JSON.parse(read('package.json')).files.includes('vendor'), 'package.json files must ship vendor/');
});

// GitHub Actions may not open pull requests in this repository, so the workflow hands over a pushed branch and a notice.
test('the archify workflow stops at the pushed branch and asks for a PR by hand', () => {
const yml = read('.github/workflows/archify.yml');
assert.doesNotMatch(yml, /gh pr create/, 'the workflow token cannot open a PR; the run must not try');
assert.doesNotMatch(yml, /pull-requests:/, 'the workflow needs no pull-requests permission');
assert.match(yml, /git push origin "archify\/\$TAG"/);
assert.equal((yml.match(/::notice title=archify \$TAG::/g) || []).length, 2, 'a notice on the run that pushes the branch and on each later run that finds it');
assert.match(yml, /compare\/main\.\.\.archify\/\$TAG\?expand=1/, 'the notice links the page that opens the PR');
assert.match(read('docs/archify.md'), /open the PR by hand/);
});
Loading