chore(deps): Bump the npm-dependencies group in /site with 4 updates #237
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| pull_request: | |
| types: [opened, synchronize, reopened, edited] | |
| push: | |
| branches: | |
| - main | |
| defaults: | |
| run: | |
| shell: bash -xeuo pipefail {0} | |
| concurrency: | |
| group: "ci-${{ github.ref }}" | |
| cancel-in-progress: true | |
| permissions: {} | |
| jobs: | |
| generate-matrix: | |
| name: Generate matrix | |
| runs-on: ubuntu-slim | |
| permissions: | |
| contents: read | |
| outputs: | |
| matrix: ${{ steps.matrix.outputs.matrix }} | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Generate CI matrix | |
| id: matrix | |
| env: | |
| BASE_SHA: ${{ github.event.pull_request.base.sha }} | |
| EVENT_ACTION: ${{ github.event.action }} | |
| EVENT_NAME: ${{ github.event_name }} | |
| run: | | |
| # Push to main: run test-tsan so Codecov has a baseline for PR | |
| # coverage comparisons. | |
| if [[ "${EVENT_NAME}" == "push" ]]; then | |
| echo 'matrix=[{"name":"Test (Thread Sanitizer)","check":"test-tsan","runner":"macos-26","xcodebuild_flags":"-enableCodeCoverage YES -enableThreadSanitizer YES","result_bundle":"TestResults-TSAN","environment":"codecov"}]' >> "${GITHUB_OUTPUT}" | |
| exit 0 | |
| fi | |
| MATRIX='[{"name":"Conventional Commits","check":"commits","runner":"ubuntu-slim","fetch_depth":"0"}' | |
| # For title/body edits, only recheck conventional commits | |
| if [[ "${EVENT_ACTION}" == "edited" ]]; then | |
| echo "matrix=${MATRIX}]" >> "${GITHUB_OUTPUT}" | |
| exit 0 | |
| fi | |
| CHANGED=$(git diff --name-only "${BASE_SHA}...HEAD") | |
| # Swift or CI workflow changes: lint + sanitizer tests | |
| if echo "${CHANGED}" | grep -qE '\.swift$|^Package\.(swift|resolved)$|^macOSdb\.xcodeproj/|^\.swiftlint\.yml$|^\.github/workflows/ci\.yml$'; then | |
| MATRIX+=',{"name":"Lint","check":"lint","runner":"macos-26"}' | |
| MATRIX+=',{"name":"Test (Thread Sanitizer)","check":"test-tsan","runner":"macos-26","xcodebuild_flags":"-enableCodeCoverage YES -enableThreadSanitizer YES","result_bundle":"TestResults-TSAN","environment":"codecov"}' | |
| MATRIX+=',{"name":"Test (Address Sanitizer)","check":"test-asan","runner":"macos-26","xcodebuild_flags":"-enableAddressSanitizer YES","result_bundle":"TestResults-ASAN"}' | |
| fi | |
| # Source changes: CodeQL (excludes xcodeproj-only changes like version bumps) | |
| if echo "${CHANGED}" | grep -qE '^Sources/|^macOSdbApp/|^Package\.(swift|resolved)$'; then | |
| MATRIX+=',{"name":"CodeQL","check":"codeql","runner":"macos-26"}' | |
| fi | |
| # Data changes: JSON schema validation | |
| if echo "${CHANGED}" | grep -qE '^data/'; then | |
| MATRIX+=',{"name":"Lint JSON","check":"lint-json","runner":"ubuntu-slim"}' | |
| fi | |
| # Site or data changes: format check + build | |
| if echo "${CHANGED}" | grep -qE '^site/|^data/'; then | |
| MATRIX+=',{"name":"Site","check":"site","runner":"ubuntu-slim"}' | |
| fi | |
| # Workflow changes: Actions security audit | |
| if echo "${CHANGED}" | grep -qE '^\.github/workflows/'; then | |
| MATRIX+=',{"name":"zizmor","check":"zizmor","runner":"ubuntu-latest"}' | |
| fi | |
| echo "matrix=${MATRIX}]" >> "${GITHUB_OUTPUT}" | |
| check: | |
| name: ${{ matrix.name }} | |
| needs: generate-matrix | |
| runs-on: ${{ matrix.runner }} | |
| environment: | |
| name: ${{ matrix.environment }} | |
| deployment: false | |
| permissions: | |
| contents: read | |
| pull-requests: read # required to fetch PR commits for conventional commit validation | |
| security-events: write # required for CodeQL and zizmor SARIF uploads | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| fetch-depth: ${{ matrix.fetch_depth || 1 }} | |
| persist-credentials: false | |
| # --- Conventional Commits --- | |
| - name: Check PR title | |
| if: matrix.check == 'commits' | |
| env: | |
| PR_TITLE: ${{ github.event.pull_request.title }} | |
| run: | | |
| PATTERN='^(feat|fix|docs|style|refactor|perf|test|build|ci|chore)(\(.+\))?: .+' | |
| if [[ ! "${PR_TITLE}" =~ ${PATTERN} ]]; then | |
| echo "::error::PR title '${PR_TITLE}' does not follow Conventional Commits." | |
| echo "" | |
| echo "Expected format: <type>(<scope>): <description>" | |
| echo "" | |
| echo "Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore" | |
| echo "" | |
| echo "Examples:" | |
| echo " feat(scanner): add Python component extraction" | |
| echo " fix(registry): correct M4 Ultra model identifier" | |
| echo " ci: add SwiftLint workflow" | |
| exit 1 | |
| fi | |
| - name: Check commit messages | |
| if: matrix.check == 'commits' | |
| env: | |
| BASE_SHA: ${{ github.event.pull_request.base.sha }} | |
| HEAD_SHA: ${{ github.event.pull_request.head.sha }} | |
| run: | | |
| PATTERN='^(feat|fix|docs|style|refactor|perf|test|build|ci|chore)(\(.+\))?: .+' | |
| FAILED=0 | |
| while IFS= read -r LINE; do | |
| SHA="${LINE%% *}" | |
| MSG="${LINE#* }" | |
| if [[ "${MSG}" == Merge\ * ]]; then | |
| continue | |
| fi | |
| if [[ ! "${MSG}" =~ ${PATTERN} ]]; then | |
| echo "::error::Commit ${SHA} does not follow Conventional Commits: '${MSG}'" | |
| FAILED=1 | |
| fi | |
| done < <(git log --format="%h %s" "${BASE_SHA}..${HEAD_SHA}") | |
| if [[ "${FAILED}" -eq 1 ]]; then | |
| echo "" | |
| echo "All commit messages must follow: <type>(<scope>): <description>" | |
| echo "Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore" | |
| exit 1 | |
| fi | |
| # --- Lint --- | |
| - name: Install lint tools | |
| if: matrix.check == 'lint' | |
| env: | |
| HOMEBREW_NO_AUTO_UPDATE: 1 | |
| HOMEBREW_NO_ENV_HINTS: 1 | |
| run: brew install swiftlint typos-cli | |
| - name: SwiftLint | |
| if: matrix.check == 'lint' | |
| run: swiftlint --strict | |
| - name: Typos | |
| if: matrix.check == 'lint' | |
| run: typos | |
| # --- Lint JSON --- | |
| - name: Lint JSON | |
| if: matrix.check == 'lint-json' | |
| run: python3 scripts/lint-json.py | |
| # --- Site --- | |
| - name: Setup Node | |
| if: matrix.check == 'site' | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version: 26 | |
| - name: Install site dependencies | |
| if: matrix.check == 'site' | |
| working-directory: site | |
| run: npm ci | |
| - name: Check formatting | |
| if: matrix.check == 'site' | |
| working-directory: site | |
| run: npm run format:check | |
| - name: Build site | |
| if: matrix.check == 'site' | |
| working-directory: site | |
| run: npm run build | |
| # --- Tests --- | |
| - name: Test | |
| if: startsWith(matrix.check, 'test-') | |
| env: | |
| XCODEBUILD_FLAGS: ${{ matrix.xcodebuild_flags }} | |
| RESULT_BUNDLE: ${{ matrix.result_bundle }} | |
| run: | | |
| xcodebuild test \ | |
| -workspace . \ | |
| -scheme macOSdb-Package \ | |
| -destination 'platform=macOS' \ | |
| -derivedDataPath ./DerivedData \ | |
| ${XCODEBUILD_FLAGS} \ | |
| -resultBundlePath "${RESULT_BUNDLE}.xcresult" \ | |
| CODE_SIGN_IDENTITY="" \ | |
| CODE_SIGNING_REQUIRED=NO \ | |
| CODE_SIGNING_ALLOWED=NO \ | |
| EXCLUDED_ARCHS=x86_64 | |
| - name: Coverage Summary | |
| if: always() && matrix.check == 'test-tsan' | |
| run: xcrun xccov view --report --only-targets TestResults-TSAN.xcresult || true | |
| - name: Export LCOV for Codecov | |
| if: success() && matrix.check == 'test-tsan' | |
| run: | | |
| PROFDATA=$(find ./DerivedData -name 'Coverage.profdata' -type f | head -1) | |
| if [[ -z "${PROFDATA}" ]]; then | |
| echo "::error::No Coverage.profdata found under ./DerivedData" | |
| exit 1 | |
| fi | |
| BINARY_ARGS=() | |
| FIRST="" | |
| while IFS= read -r xctest; do | |
| name=$(basename "${xctest}" .xctest) | |
| bin="${xctest}/Contents/MacOS/${name}" | |
| [[ -f "${bin}" ]] || continue | |
| if [[ -z "${FIRST}" ]]; then FIRST="${bin}"; else BINARY_ARGS+=(-object "${bin}"); fi | |
| done < <(find ./DerivedData/Build/Products -name '*.xctest' -type d) | |
| if [[ -z "${FIRST}" ]]; then | |
| echo "::error::No xctest binaries found under ./DerivedData/Build/Products" | |
| exit 1 | |
| fi | |
| xcrun llvm-cov export -format=lcov \ | |
| -ignore-filename-regex='(Tests/|\.build/|DerivedData/|/Checkouts/|/SourcePackages/)' \ | |
| "${FIRST}" \ | |
| ${BINARY_ARGS[@]+"${BINARY_ARGS[@]}"} \ | |
| -instr-profile="${PROFDATA}" \ | |
| > coverage.lcov | |
| echo "lcov: $(wc -l < coverage.lcov) lines" | |
| - name: Upload coverage to Codecov | |
| if: success() && matrix.check == 'test-tsan' | |
| uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6.0.1 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: coverage.lcov | |
| fail_ci_if_error: false | |
| - name: Convert xcresult to JUnit | |
| if: ${{ !cancelled() && matrix.check == 'test-tsan' }} | |
| env: | |
| RESULT_BUNDLE: ${{ matrix.result_bundle }} | |
| run: python3 scripts/xcresult-to-junit.py "${RESULT_BUNDLE}.xcresult" > junit.xml | |
| - name: Upload test results to Codecov | |
| if: ${{ !cancelled() && matrix.check == 'test-tsan' }} | |
| uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6.0.1 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: junit.xml | |
| fail_ci_if_error: false | |
| report_type: test_results | |
| - name: Upload Test Results | |
| if: always() && startsWith(matrix.check, 'test-') | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: ${{ matrix.result_bundle }} | |
| path: ${{ matrix.result_bundle }}.xcresult | |
| retention-days: 14 | |
| # --- CodeQL --- | |
| - name: Initialize CodeQL | |
| if: matrix.check == 'codeql' | |
| uses: github/codeql-action/init@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 | |
| with: | |
| languages: swift | |
| build-mode: manual | |
| - name: Build for CodeQL | |
| if: matrix.check == 'codeql' | |
| run: | | |
| xcodebuild \ | |
| -project macOSdb.xcodeproj \ | |
| -scheme macOSdb \ | |
| -destination 'generic/platform=macOS' \ | |
| -configuration Debug \ | |
| CODE_SIGN_IDENTITY="" \ | |
| CODE_SIGNING_REQUIRED=NO \ | |
| CODE_SIGNING_ALLOWED=NO \ | |
| EXCLUDED_ARCHS=x86_64 \ | |
| build | |
| - name: CodeQL Analysis | |
| if: matrix.check == 'codeql' | |
| uses: github/codeql-action/analyze@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 | |
| with: | |
| category: "/language:swift" | |
| # --- zizmor --- | |
| - name: Run zizmor | |
| if: matrix.check == 'zizmor' | |
| uses: zizmorcore/zizmor-action@5f14fd08f7cf1cb1609c1e344975f152c7ee938d # v0.5.6 | |
| with: | |
| persona: auditor | |
| conclusion: | |
| name: conclusion | |
| needs: check | |
| runs-on: ubuntu-slim | |
| if: always() | |
| steps: | |
| - name: Result | |
| env: | |
| CHECK_RESULT: ${{ needs.check.result }} | |
| run: test "${CHECK_RESULT}" = "success" |