Skip to content

chore(deps): update dev dependencies (non-major) #645

chore(deps): update dev dependencies (non-major)

chore(deps): update dev dependencies (non-major) #645

Workflow file for this run

name: Validate CI
on:
pull_request:
branches:
- next
- main
types:
- opened
- synchronize
- ready_for_review
- reopened
# `edited` re-runs validation when the PR base branch changes, since the
# base-dependent guards below (changelog/plan-file history) compare
# against it. It also fires on title/body edits — a small amount of extra
# runs we accept to keep base-change reruns correct.
- edited
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
name: Run Unit Tests on Node v${{ matrix.node-version }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# 22 = engines support floor; 24 = project default (.nvmrc).
node-version: [22, 24]
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Setup and build
uses: ./.github/actions/setup
with:
node-version: ${{ matrix.node-version }}
- name: Run unit tests
run: npm test
lint:
name: Run Code Checks
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Setup and build
uses: ./.github/actions/setup
- name: Biome check
run: npm run check:ci
- name: TypeScript type check
run: npx tsc --noEmit
- name: TypeScript type check (tests)
run: npm run typecheck:test
actionlint:
name: Lint Workflows
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Run actionlint
uses: docker://rhysd/actionlint@sha256:b1934ee5f1c509618f2508e6eb47ee0d3520686341fec936f3b79331f9315667 # v1.7.12
with:
args: -color
env:
# SC2016 (single-quoted `${...}` don't expand) fires on the many
# intentional literal strings we echo into PR comments (markdown +
# bash examples that must stay literal). Exclude just that one
# info-level rule; all other shellcheck findings still fail the job.
SHELLCHECK_OPTS: --exclude=SC2016
knip:
name: Detect Dead Code
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
# Build runs codegen (prebuild) so src/gql exists and imports resolve.
- name: Setup and build
uses: ./.github/actions/setup
- name: Run knip
id: knip
run: |
set +e
npm run --silent knip:ci > knip-report.md
echo "exit_code=$?" >> "$GITHUB_OUTPUT"
set -e
- name: Compose PR comment
if: always()
run: |
if [ "${{ steps.knip.outputs.exit_code }}" = "0" ]; then
{
echo '## ✅ knip — no dead code'
echo
echo 'No unused files, exports, types, or dependencies detected.'
} > knip-comment.md
else
{
echo '## 🧹 knip found dead code'
echo
cat knip-report.md
echo
echo '### Fix it locally'
echo
echo '```bash'
echo 'npm run generate # ensure generated GraphQL types exist'
echo 'npm run knip # see the full report'
echo 'npx knip --fix --allow-remove-files # auto-remove unused exports/files, then review the diff'
echo '```'
echo
echo 'If a finding is a false positive (dynamically-wired code knip cannot trace), add a narrow entry to `knip.json` explaining why.'
} > knip-comment.md
fi
- name: Save PR number
if: always()
run: echo "${{ github.event.pull_request.number }}" > pr-number.txt
# GITHUB_TOKEN is forced read-only for pull_request events from forks,
# so this job can't post the comment itself regardless of permissions:.
# Upload the rendered comment + PR number as an artifact; a separate
# workflow_run-triggered workflow (which does get a writable token)
# downloads it and posts the comment. See .github/workflows/knip-comment.yml.
- name: Upload knip comment artifact
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: knip-comment
path: |
knip-comment.md
pr-number.txt
retention-days: 1
- name: Fail if dead code found
if: steps.knip.outputs.exit_code != '0'
run: |
echo "::error::knip found dead code — see the PR comment for details"
exit 1
commitlint:
name: Validate Commit Messages
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- name: Setup (no build)
uses: ./.github/actions/setup
with:
build: "false"
- name: Validate PR commit range
run: |
npx commitlint \
--from "${{ github.event.pull_request.base.sha }}" \
--to "${{ github.event.pull_request.head.sha }}" \
--verbose
smoke-test:
name: Run Package Install Smoke Test
runs-on: ubuntu-latest
needs: [test]
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
# No build here: verify:packed-binaries runs `npm pack`, whose `prepack`
# builds (and generates) the package the same way a consumer install would.
- name: Setup (no build)
uses: ./.github/actions/setup
with:
build: "false"
- name: Verify packed binaries
run: npm run verify:packed-binaries
guard-plan-files:
name: Reject Plan Files
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- name: Check for docs/plans/*.md in branch history
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
base_ref="origin/${GITHUB_BASE_REF:-main}"
plan_files=$(git log "$base_ref"..HEAD \
--diff-filter=A --name-only --pretty=format: \
-- 'docs/plans/*.md' | sed '/^$/d')
if [ -n "$plan_files" ]; then
echo "::error::Found plan files in branch history"
# GITHUB_TOKEN is forced read-only for pull_request events from
# forks, so posting a comment would fail there regardless of
# permissions:. The ::error:: above still surfaces in the checks
# UI, so skip the comment rather than fail this step on forks.
if [ "${{ github.event.pull_request.head.repo.full_name }}" = "${{ github.repository }}" ]; then
printf '%s\n' \
'<!-- linearis:guard-plan-files -->' \
'' \
'> [!WARNING]' \
'> Found `docs/plans/*.md` files in this branch'"'"'s history.' \
'>' \
'> Plan files in `docs/plans/` are working artifacts created by AI agents during the design phase. Once the implementation they describe is complete and the PR is ready for review, these files serve no further purpose — they are not reference docs, not changelogs, and not part of the shipped project.' \
'>' \
'> Leaving them in the commit history would add noise and suggest unresolved or incomplete work.' \
'>' \
'> **Remove them by rebasing and dropping the commits that introduced them:**' \
'> ```bash' \
'> git rebase -i main' \
'> # drop the commits that added docs/plans/*.md, then force-push' \
'> git push --force-with-lease' \
'> ```' \
| gh pr comment ${{ github.event.pull_request.number }} --body-file -
fi
exit 1
fi
echo "No plan files found — OK"
guard-changelog-history:
name: Guard CHANGELOG History in PR
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- name: Detect CHANGELOG.md in branch history
shell: bash
run: |
set -euo pipefail
if [ "${GITHUB_HEAD_REF:-}" = "next" ] && [ "${GITHUB_BASE_REF:-}" = "main" ]; then
echo "Promotion PR next -> main detected. Skipping changelog history guard."
exit 0
fi
base_ref="origin/${GITHUB_BASE_REF:-main}"
output=$(git log "$base_ref"..HEAD --name-status --pretty=format: -- CHANGELOG.md | sed '/^$/d')
if [ -n "$output" ]; then
echo "::error::CHANGELOG.md is release-workflow-owned and must not appear in PR branch history"
echo "Drop or amend commits that touch CHANGELOG.md, then push with --force-with-lease"
echo
echo "$output"
exit 1
fi
echo "No CHANGELOG.md history violations — OK"