Skip to content

Merge branch 'v5' into scanner/fix-17426 #11041

Merge branch 'v5' into scanner/fix-17426

Merge branch 'v5' into scanner/fix-17426 #11041

Workflow file for this run

name: Dashboard Lint
# The checker itself is in scope, not just the files it checks (#5388).
# The syntax-check job runs .github/scripts/check-inline-js.js, but the filter
# named only 'dashboard/**' — so a change that broke the checker (or silently
# stopped it detecting anything) ran no CI at all, and the next dashboard PR
# would then pass against a checker nobody had exercised. The workflow file is
# listed for the same reason: an edit to the `find` invocation here changes
# what gets checked, and that edit must run the job it changes.
#
# THE SHIPPED DASHBOARD IS src/pkg/dashboard/static/ (#5516). That is the tree
# `//go:embed static` compiles into the binary and serves; dashboard/index.html
# is a different, smaller file. Until this was added, every edit to the
# dashboard an operator actually loads ran no lint at all — which is how a
# call to an undefined helper reached a released image and broke the login
# flow. Both trees are checked now, and both are in the path filter, so a PR
# touching either runs the job.
#
# Two passes (see .github/scripts/check-inline-js.js): `node --check` for
# syntax, then ESLint `no-undef` over the concatenated inline blocks. The
# second pass is what would have caught #5516 — `apiFetch is not defined`
# parses fine. Its dependency is exact-pinned under .github/scripts/, which is
# why '.github/scripts/**' (package.json, lockfile, checker) is in the filter.
on:
push:
paths:
- 'dashboard/**'
- 'src/pkg/dashboard/static/**'
- '.github/scripts/**'
- '.github/workflows/dashboard-lint.yml'
pull_request:
paths:
- 'dashboard/**'
- 'src/pkg/dashboard/static/**'
- '.github/scripts/**'
- '.github/workflows/dashboard-lint.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
permissions:
contents: read
jobs:
syntax-check:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version: '22'
cache: npm
cache-dependency-path: .github/scripts/package-lock.json
- name: Guard shared node tool cache (repair a half-written entry)
# setup-node reports "Found in cache" for a node/<ver>/x64 entry whose
# .complete marker exists but bin/npm does not (#10505, #10518). The
# canary repairs this too, but its cron is starved to a ~5h cadence, so
# heal the node from the hot path: drop the marker (never the directory,
# a sibling job may be mid-run) so the next job re-extracts.
if: ${{ always() }}
run: |
set -u
command -v npm >/dev/null 2>&1 && exit 0
for marker in "${RUNNER_TOOL_CACHE:-/nonexistent}"/node/*/x64.complete; do
[ -e "$marker" ] || continue
dir="${marker%.complete}"
[ -x "$dir/bin/npm" ] && continue
echo "::warning::node tool cache $dir has a .complete marker but no executable bin/npm; removing the marker so the next job on $RUNNER_NAME rebuilds it"
rm -f "$marker"
done
echo "::error::npm is not on PATH after actions/setup-node on $RUNNER_NAME (half-written shared tool cache, see #10518); marker removed, re-run this job"
exit 1
# eslint + globals are exact-pinned in .github/scripts/package.json and
# resolved from its lockfile; --ignore-scripts keeps install hooks out of
# CI. The checker fails (does not skip) if this step was not run.
- name: Install pinned ESLint for the no-undef pass
run: npm ci --ignore-scripts --no-audit --no-fund
working-directory: .github/scripts
- name: Syntax-check and no-undef-check inline JavaScript
run: |
find dashboard src/pkg/dashboard/static -name '*.html' -print0 \
| xargs -0 --no-run-if-empty node .github/scripts/check-inline-js.js
server-tests:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version: '22'
cache: npm
cache-dependency-path: dashboard/package-lock.json
- name: Guard shared node tool cache (repair a half-written entry)
# setup-node reports "Found in cache" for a node/<ver>/x64 entry whose
# .complete marker exists but bin/npm does not (#10505, #10518). The
# canary repairs this too, but its cron is starved to a ~5h cadence, so
# heal the node from the hot path: drop the marker (never the directory,
# a sibling job may be mid-run) so the next job re-extracts.
if: ${{ always() }}
run: |
set -u
command -v npm >/dev/null 2>&1 && exit 0
for marker in "${RUNNER_TOOL_CACHE:-/nonexistent}"/node/*/x64.complete; do
[ -e "$marker" ] || continue
dir="${marker%.complete}"
[ -x "$dir/bin/npm" ] && continue
echo "::warning::node tool cache $dir has a .complete marker but no executable bin/npm; removing the marker so the next job on $RUNNER_NAME rebuilds it"
rm -f "$marker"
done
echo "::error::npm is not on PATH after actions/setup-node on $RUNNER_NAME (half-written shared tool cache, see #10518); marker removed, re-run this job"
exit 1
- name: Dashboard server tests
run: npm ci --no-audit --no-fund && npm test
working-directory: dashboard