chore(deps-dev): bump tsx from 4.22.0 to 4.22.1 in the development-dependencies group #1893
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: Test and Report | |
| on: | |
| push: | |
| branches: ["main"] | |
| pull_request: | |
| branches: ["main"] | |
| # Set default permissions to read-only | |
| permissions: read-all | |
| # Resilience against transient npm registry / mirror failures. | |
| # Applied to every job; npm honours these env vars natively. | |
| env: | |
| # Single source of truth for all setup-node steps and cache keys in this workflow. | |
| NODE_VERSION: "26" | |
| NPM_CONFIG_FETCH_RETRIES: "5" | |
| NPM_CONFIG_FETCH_RETRY_MINTIMEOUT: "20000" | |
| NPM_CONFIG_FETCH_RETRY_MAXTIMEOUT: "120000" | |
| NPM_CONFIG_FETCH_TIMEOUT: "300000" | |
| jobs: | |
| prepare: | |
| runs-on: ubuntu-latest | |
| # Only needs read permissions | |
| permissions: | |
| contents: read # Required to check out code | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 | |
| with: | |
| egress-policy: audit | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| # Built-in npm cache (single source of truth — no extra actions/cache step). | |
| # Cache key automatically derived from package-lock.json + Node major version. | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm ci | |
| build-validation: | |
| needs: prepare | |
| runs-on: ubuntu-latest | |
| # Needs write permissions to upload artifacts | |
| permissions: | |
| contents: write # Required to check out code | |
| actions: read # Required to use GitHub actions | |
| id-token: write # Required for attestation | |
| pull-requests: write # Required to upload artifacts (implicit permission) | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 | |
| with: | |
| egress-policy: audit | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| # Built-in npm cache (single source of truth — no extra actions/cache step). | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Cache build artifacts | |
| id: build-cache | |
| uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | |
| with: | |
| path: dist | |
| # Unique key: cache-version + OS + Node major + lockfile hash + source hash + tsconfig hash. | |
| # Bumping the `build-vN-` prefix expires every old build cache atomically. | |
| key: build-v2-${{ runner.os }}-node${{ env.NODE_VERSION }}-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('src/**/*.ts', 'tsconfig*.json') }} | |
| # TypeScript type checking | |
| - name: Type check | |
| run: npm run type-check | |
| # TypeScript type checking for test helpers (mockFactory.ts, assertions.ts) | |
| - name: Type check test helpers | |
| run: npm run type-check:helpers | |
| # Run linter | |
| - name: Lint | |
| run: npm run lint | |
| # Check for unused dependencies with knip | |
| - name: Check for unused dependencies | |
| run: npm run knip | |
| # Build the project (ensures dist/ output is valid) | |
| - name: Build | |
| # cache-hit is emitted as the string "true"/"false" by actions/cache. | |
| if: steps.build-cache.outputs.cache-hit != 'true' | |
| run: npm run build | |
| # Verify package can be packed (catches prepublish issues before release) | |
| - name: Validate package | |
| run: npm pack --dry-run | |
| # Check licenses | |
| - name: Check licenses | |
| run: npm run test:licenses | |
| - name: Generate SBOM | |
| uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0.24.0 | |
| id: sbom | |
| with: | |
| format: spdx-json | |
| output-file: european-parliament-mcp-server.spdx.json | |
| artifact-name: european-parliament-mcp-server | |
| - name: Install SBOMQS | |
| # Resilient download: retry transient network failures, fail fast on hard errors. | |
| run: | | |
| set -euo pipefail | |
| SBOMQS_VERSION="1.2.0" | |
| SBOMQS_BINARY="sbomqs-linux-amd64" | |
| SBOMQS_DOWNLOAD_PATH="/tmp/sbomqs" | |
| SBOMQS_BASE_URL="https://github.com/interlynk-io/sbomqs/releases/download/v${SBOMQS_VERSION}" | |
| curl --fail --location --show-error --silent \ | |
| --retry 5 --retry-delay 5 --retry-max-time 120 \ | |
| --connect-timeout 30 --max-time 180 \ | |
| -o "${SBOMQS_DOWNLOAD_PATH}" \ | |
| "${SBOMQS_BASE_URL}/${SBOMQS_BINARY}" | |
| curl --fail --location --show-error --silent \ | |
| --retry 5 --retry-delay 5 --retry-max-time 120 \ | |
| --connect-timeout 30 --max-time 180 \ | |
| -o /tmp/sbomqs_checksums.txt \ | |
| "${SBOMQS_BASE_URL}/sbomqs_${SBOMQS_VERSION}_checksums.txt" | |
| expected_sha="$(awk -v file="${SBOMQS_BINARY}" '$NF == file { print $1; exit }' /tmp/sbomqs_checksums.txt)" | |
| if [ -z "${expected_sha}" ]; then | |
| echo "::error::Unable to find checksum entry for ${SBOMQS_BINARY} in checksums file. Verify the release asset and checksum format." | |
| exit 1 | |
| fi | |
| printf '%s %s\n' "${expected_sha}" "${SBOMQS_DOWNLOAD_PATH}" | sha256sum -c - | |
| sudo mv "${SBOMQS_DOWNLOAD_PATH}" /usr/local/bin/sbomqs | |
| sudo chmod a+x /usr/local/bin/sbomqs | |
| - name: Details SBOM Quality | |
| run: sbomqs score european-parliament-mcp-server.spdx.json --detailed | |
| - name: Check SBOM Quality | |
| run: | | |
| score=$(sbomqs score european-parliament-mcp-server.spdx.json --json | jq '.files[0].avg_score') | |
| echo "SBOM Score: $score/10" | |
| if (( $(echo "$score < 7.0" | bc -l) )); then | |
| echo "::error::SBOM quality score too low: $score" | |
| exit 1 | |
| fi | |
| - name: Upload build artifacts | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: build-output | |
| path: | | |
| dist | |
| european-parliament-mcp-server.spdx.json | |
| if-no-files-found: warn | |
| unit-tests: | |
| needs: [prepare, build-validation] | |
| runs-on: ubuntu-latest | |
| # Needs write permissions to upload artifacts | |
| permissions: | |
| contents: write # Required to check out code | |
| actions: read # Required to use GitHub actions | |
| checks: write # Required to upload artifacts (implicit permission) | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 | |
| with: | |
| egress-policy: audit | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| # Built-in npm cache (single source of truth — no extra actions/cache step). | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Run unit tests with coverage | |
| run: npm run test:coverage | |
| - name: Check coverage thresholds | |
| run: | | |
| # Extract coverage from report | |
| if [ -f "coverage/coverage-summary.json" ]; then | |
| COVERAGE=$(jq '.total.lines.pct' coverage/coverage-summary.json) | |
| echo "Current coverage: $COVERAGE%" | |
| # Convert coverage to integer (percentage * 100) for comparison | |
| COVERAGE_INT=$(awk -v c="$COVERAGE" 'BEGIN { printf "%d", c * 100 }') | |
| # Check if coverage meets requirements (80% minimum = 8000) | |
| if [ "$COVERAGE_INT" -lt 8000 ]; then | |
| echo "⚠️ Coverage $COVERAGE% is below required 80%" | |
| echo "::warning::Coverage $COVERAGE% is below required 80%" | |
| else | |
| echo "✅ Coverage $COVERAGE% meets requirement" | |
| fi | |
| else | |
| echo "⚠️ Coverage summary not found" | |
| fi | |
| continue-on-error: true | |
| - name: Upload coverage to Codecov | |
| uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v5.3.2 | |
| with: | |
| files: ./coverage/coverage-final.json | |
| fail_ci_if_error: false | |
| verbose: true | |
| continue-on-error: true | |
| - name: Upload coverage report | |
| if: always() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: coverage-report | |
| path: coverage | |
| if-no-files-found: warn | |
| report: | |
| needs: [unit-tests] | |
| runs-on: ubuntu-latest | |
| if: always() | |
| # Needs write permissions to upload artifacts | |
| permissions: | |
| contents: write # Required to check out code | |
| actions: read # Required to use GitHub actions | |
| checks: write # Required to upload artifacts (implicit permission) | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 | |
| with: | |
| egress-policy: audit | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| path: artifacts | |
| continue-on-error: true | |
| - name: Upload combined reports | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: test-reports | |
| path: | | |
| artifacts/coverage-report | |
| if-no-files-found: warn | |
| - name: Test summary | |
| run: | | |
| echo "## Test Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### Status" >> $GITHUB_STEP_SUMMARY | |
| echo "- ✅ Build validation: Passed" >> $GITHUB_STEP_SUMMARY | |
| echo "- ✅ Unit tests: Passed" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### Note" >> $GITHUB_STEP_SUMMARY | |
| echo "Integration and E2E tests run in separate workflow: integration-tests.yml" >> $GITHUB_STEP_SUMMARY |