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
5 changes: 3 additions & 2 deletions .github/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ The `audit` CI job runs the always-hard-fail ones (knip / cspell / size-limit /

## CI / deployment

Three workflows in [.github/workflows/](workflows/):
The main workflows in [.github/workflows/](workflows/):

- **[ci.yml](workflows/ci.yml)** — runs on every push / PR. Four jobs in parallel:
- **frontend** (ubuntu): `tsc --noEmit`, `npm run coverage`, `npm run build`, `audit:a11y`. Uploads `coverage/lcov.info` to Codecov with flag `frontend`.
Expand All @@ -197,7 +197,8 @@ Three workflows in [.github/workflows/](workflows/):
- **advisory** (ubuntu): cargo-deny + lychee + npm audit, results posted as a sticky PR comment. Step-level `continue-on-error: true` keeps the comment posting even when an audit fails; a final step re-fails the job on lychee breakage so broken links block merges.
- **[docs.yml](workflows/docs.yml)** — runs on push to `main` when `docs/**`, `src/**`, `src-tauri/**`, or `.config/typedoc/**` change. Builds the VitePress site + rustdoc + TypeDoc, deploys to GitHub Pages.
- **[docs-preview.yml](workflows/docs-preview.yml)** — runs on `pull_request` against the same path set. Mirrors the production docs build and pushes the result to Netlify as a per-PR preview, then sticky-comments the URL on the PR. Requires `NETLIFY_AUTH_TOKEN` (user token) and `NETLIFY_SITE_ID` (per-site) repo secrets. Skips fork PRs (no secret access). Production deploys stay on GitHub Pages via `docs.yml` — Netlify is preview-only.
- **[release.yml](workflows/release.yml)** — runs on `v*` tag push (or `workflow_dispatch`). Full bundle via `tauri-action` across all platforms, creates a draft GitHub release.
- **[release.yml](workflows/release.yml)** — runs on `v*` tag push (or `workflow_dispatch`). Full bundle via `tauri-action` across all platforms, creates a draft GitHub release. It stays in `ci.yml`'s `paths-ignore`, so editing it does not run the test matrix — but `src/test-fixtures/scoop-manifest.test.ts` reads it to pin the portable-zip asset name, which is why `audit.yml` (no path filter) runs that test too.
- **[bump-cask.yml](workflows/bump-cask.yml)** / **[bump-scoop.yml](workflows/bump-scoop.yml)** — run on `release: published` and commit `Casks/entracte.rb` / `bucket/entracte.json` straight to `main`. Actions cannot open PRs on this repo (`can_approve_pull_request_reviews` is off — see #349), so each ends with an `if: failure()` step that files or comments on an issue; nothing downstream would otherwise notice a red run. Stable releases only.

Codecov targets: project + patch, both `informational: true` (no merge block on coverage drops) — see [.github/codecov.yml](codecov.yml).

Expand Down
8 changes: 8 additions & 0 deletions .github/audit/cspell/project-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -205,3 +205,11 @@ dryrun
worktree
worktrees
triggerable
Scoop
scoop
checkver
autoupdate
pwsh
APPDATA
Chocolatey
cnotcontains
8 changes: 8 additions & 0 deletions .github/workflows/audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ jobs:
- name: workflow shell syntax
run: npm run audit:workflow-shell

# The Scoop packaging pins span files that ci.yml's `paths-ignore`
# excludes — `.github/workflows/release.yml` and `docs/**` — so a rename
# in either would skip ci.yml's `frontend` job and sail past the one test
# that catches it. This workflow has no path filter, which is exactly the
# property the pins need, and the job already has `npm ci` (#359).
- name: cross-file packaging pins
run: npm test -- src/test-fixtures/scoop-manifest.test.ts

# Advisory audits: surface signal without blocking merges.
# cargo-deny covers licenses + CVEs + duplicate-version checks.
# npm audit is externally-validated and can flap, so it stays advisory.
Expand Down
38 changes: 38 additions & 0 deletions .github/workflows/build-preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,44 @@ jobs:
echo '```'
} >> "$GITHUB_STEP_SUMMARY"

# Guard the Scoop portable zip (#359). The release job packages it with
# pwsh, which `audit:workflow-shell` cannot check (it parses bash only),
# so a wrong exe path or an empty archive would otherwise first surface
# at release time, with the Windows bundles already built. Same class of
# bug as the AppImage icon below: invisible unless something looks inside
# the archive.
#
# This job is opt-in (`build:installers`), so this is a pre-release
# smoke test to run when the packaging changes — not a per-PR gate.
#
# `--debug` here, so the exe is under target/debug.
- name: Verify the portable zip can be packaged
if: matrix.platform == 'windows-latest'
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'
$stage = Join-Path $env:RUNNER_TEMP 'portable-check'
New-Item -ItemType Directory -Force -Path $stage | Out-Null
Copy-Item src-tauri/target/debug/entracte.exe (Join-Path $stage 'Entracte.exe')
Copy-Item LICENSE $stage
Copy-Item NOTICE $stage
$zip = Join-Path $env:RUNNER_TEMP 'portable-check.zip'
Compress-Archive -Path "$stage/*" -DestinationPath $zip -Force
Add-Type -AssemblyName System.IO.Compression.FileSystem
$archive = [IO.Compression.ZipFile]::OpenRead($zip)
try { $names = $archive.Entries.FullName } finally { $archive.Dispose() }
Write-Output "portable zip contents: $($names -join ', ')"
# `-cnotcontains`, not `-notcontains`: PowerShell's default string
# comparison is case-INsensitive, so `-notcontains` would accept an
# `entracte.exe` that never got renamed and pass on exactly the bug
# this step exists to catch.
if ($names -cnotcontains 'Entracte.exe') {
throw "no Entracte.exe at the zip root - the Scoop manifest bin/shortcuts would break"
}
if ($names -cnotcontains 'NOTICE') {
throw "no NOTICE at the zip root - Apache-2.0 4(d) requires it in a redistribution"
}

# Guard the AppImage's required AppDir files. tauri-bundler < 2.9.4
# wrote `.DirIcon` and the `.desktop` entry as ABSOLUTE symlinks
# pointing into the build machine's AppDir, so once the AppImage is
Expand Down
16 changes: 15 additions & 1 deletion .github/workflows/bump-cask.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ jobs:
- uses: actions/checkout@v7
with:
ref: main
# Full history, like bump-scoop.yml: the commit step below rebases if
# main moved while the release was being published, and a shallow
# clone has no merge base to rebase onto.
fetch-depth: 0

- name: Fetch SHA256SUMS.txt
env:
Expand Down Expand Up @@ -211,7 +215,17 @@ jobs:
if: failure()
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ steps.meta.outputs.tag }}
# Without GH_REPO, `gh issue` has no base repository to resolve: the
# only step that can fail before the checkout is the tag validation
# above, and at that point there is no git remote to infer one from —
# so the loud-failure mechanism would itself be silent.
GH_REPO: ${{ github.repository }}
# Taken from the event, NOT from `steps.meta.outputs.tag`: the tag
# validation in that step is the one thing that can fail before the
# output is published, which is exactly when this reporter runs — and
# "failed for unknown" is not a bug report anyone can act on. Same
# derivation the `concurrency` group above uses.
TAG: ${{ github.event.release.tag_name || inputs.tag }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
tag="${TAG:-unknown}"
Expand Down
Loading
Loading