Skip to content

test(phase-22b): cover optional-lastName edit in settings panel #168

test(phase-22b): cover optional-lastName edit in settings panel

test(phase-22b): cover optional-lastName edit in settings panel #168

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
name: Build (${{ matrix.os }})
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '20'
cache: npm
cache-dependency-path: |
backend/package-lock.json
frontend/package-lock.json
- name: Backend — install & typecheck
working-directory: backend
run: |
npm ci
npx tsc --noEmit
- name: Frontend — install & typecheck
working-directory: frontend
run: |
npm ci
npx tsc --noEmit
secret-scan:
name: Built-bundle secret scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '20'
cache: npm
cache-dependency-path: frontend/package-lock.json
- name: Frontend — install & build
working-directory: frontend
run: |
npm ci
npm run build
# Fails the build if the Supabase service-role JWT (or its literal
# "role":"service_role" marker) ever lands in a shipped client bundle.
# The backend holds service-role; frontend never should. A bundler
# misconfig (e.g. an accidental `import` from a backend-only file, or
# a mis-named VITE_* env) would leak it silently without this gate.
- name: Scan dist/ for service-role markers
working-directory: frontend
run: |
set -euo pipefail
if grep -r -E '"role"\s*:\s*"service_role"|SUPABASE_SERVICE_ROLE_KEY' dist/; then
echo "::error::Frontend bundle contains a service-role marker. Refuse to ship."
exit 1
fi
echo "No service-role markers in frontend/dist."
content-lint:
name: Content lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '20'
cache: npm
cache-dependency-path: frontend/package-lock.json
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: '3.12'
- name: Frontend — install & content-lint
working-directory: frontend
run: |
npm ci
npm run lint:content
solutions-pass:
name: Verify golden solutions
needs: content-lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '20'
cache: npm
cache-dependency-path: frontend/package-lock.json
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: '3.12'
- name: Frontend — install & verify solutions
working-directory: frontend
run: |
npm ci
npm run verify:solutions
test:
name: Test (${{ matrix.os }})
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '20'
cache: npm
cache-dependency-path: |
backend/package-lock.json
frontend/package-lock.json
- name: Backend — install & test
working-directory: backend
run: |
npm ci
npm test
- name: Frontend — install & test
working-directory: frontend
run: |
npm ci
npm test
powershell:
name: PowerShell parse + lint
runs-on: windows-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Parse all .ps1 files
shell: pwsh
run: |
$failed = $false
Get-ChildItem -Recurse -File -Include *.ps1 | ForEach-Object {
$errors = $null
[System.Management.Automation.Language.Parser]::ParseFile(
$_.FullName, [ref]$null, [ref]$errors
) | Out-Null
if ($errors -and $errors.Count -gt 0) {
Write-Host "Parse errors in $($_.FullName):" -ForegroundColor Red
$errors | ForEach-Object { Write-Host " $_" }
$script:failed = $true
}
}
if ($failed) { exit 1 }
- name: PSScriptAnalyzer (errors only)
shell: pwsh
run: |
Install-Module -Name PSScriptAnalyzer -Force -Scope CurrentUser -SkipPublisherCheck
$results = Invoke-ScriptAnalyzer -Path . -Recurse -Severity Error
if ($results) {
$results | Format-Table -AutoSize
exit 1
}
Write-Host "No PSScriptAnalyzer errors."
shellcheck:
name: Shellcheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Install shellcheck
run: sudo apt-get update && sudo apt-get install -y shellcheck
- name: Run shellcheck
run: |
find . -type f -name "*.sh" \
-not -path "*/node_modules/*" \
-not -path "./temp/*" \
-print0 | xargs -0 --no-run-if-empty shellcheck --severity=warning
cloud-init-drift:
# I-4 (bucket 7): cloud-init.yaml is consumed by Azure *once* per VM
# provision — after first boot, the live VM runs copies of those scripts
# from /usr/local/bin/ and /etc/systemd/system/ that never re-sync from
# the repo. So a PR editing cloud-init.yaml does nothing to production
# unless someone SSHes in and applies the diff manually, or the VM is
# re-provisioned. Surface that as an explicit warning so the next
# reviewer doesn't assume the deploy pipeline will propagate it.
#
# Also shellcheck the embedded refresh-env script — cloud-init.yaml
# ships shell-in-YAML that the main shellcheck job's `*.sh` glob misses.
name: Cloud-init drift warning
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 0
- name: Warn on cloud-init.yaml edits
run: |
set -euo pipefail
base="${{ github.event.pull_request.base.sha }}"
if git diff --name-only "$base"...HEAD | grep -qE '^infra/azure/cloud-init\.yaml$'; then
echo "::warning file=infra/azure/cloud-init.yaml::cloud-init.yaml changed in this PR. The live VM still runs scripts baked in at first-boot — diff against /usr/local/bin/refresh-env on the VM and apply any needed changes by SSH, or plan a re-provision."
else
echo "cloud-init.yaml unchanged in this PR."
fi
- name: Install shellcheck
run: sudo apt-get update && sudo apt-get install -y shellcheck
- name: Shellcheck embedded refresh-env script
run: |
set -euo pipefail
mkdir -p /tmp/cloud-init-extract
awk '
/^ - path: \/usr\/local\/bin\/refresh-env$/ { capture = 1; next }
capture && emitting && /^ - path:/ { exit }
capture && /^ content: \|/ { emitting = 1; next }
emitting {
# Strip the 6-space YAML indent from the heredoc body.
sub(/^ /, "")
print
}
' infra/azure/cloud-init.yaml > /tmp/cloud-init-extract/refresh-env
if [ ! -s /tmp/cloud-init-extract/refresh-env ]; then
echo "::error::Failed to extract refresh-env from cloud-init.yaml — check the awk delimiter in ci.yml"
exit 1
fi
shellcheck --severity=warning /tmp/cloud-init-extract/refresh-env
line-endings:
name: Line-endings (Windows checkout)
runs-on: windows-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: .sh files must be LF
shell: pwsh
run: |
$failed = @()
Get-ChildItem -Recurse -File -Include *.sh |
Where-Object { $_.FullName -notmatch "node_modules" } |
ForEach-Object {
$bytes = [System.IO.File]::ReadAllBytes($_.FullName)
if (($bytes | Where-Object { $_ -eq 13 }).Count -gt 0) {
$failed += $_.FullName
}
}
if ($failed) {
Write-Host ".sh files with CR bytes (expected LF only):" -ForegroundColor Red
$failed | ForEach-Object { Write-Host " $_" }
exit 1
}
Write-Host "All .sh files are LF."
- name: .ps1 files must be CRLF
shell: pwsh
run: |
$failed = @()
Get-ChildItem -Recurse -File -Include *.ps1 |
Where-Object { $_.FullName -notmatch "node_modules" } |
ForEach-Object {
$bytes = [System.IO.File]::ReadAllBytes($_.FullName)
$cr = ($bytes | Where-Object { $_ -eq 13 }).Count
$lf = ($bytes | Where-Object { $_ -eq 10 }).Count
if ($lf -gt 0 -and $cr -ne $lf) {
$failed += $_.FullName
}
}
if ($failed) {
Write-Host ".ps1 files missing CRLF line endings:" -ForegroundColor Red
$failed | ForEach-Object { Write-Host " $_" }
exit 1
}
Write-Host "All .ps1 files are CRLF."