Beacon Dashboard v1.1 — Filters, Exports, Alerts (120-150 RTC) #1441
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: BCOS Checks | |
| on: | |
| pull_request: | |
| types: [opened, synchronize, reopened, labeled, unlabeled] | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| jobs: | |
| label-gate: | |
| name: Review Tier Label Gate | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Require BCOS label for non-doc PRs | |
| uses: actions/github-script@v8 | |
| with: | |
| script: | | |
| const owner = context.repo.owner; | |
| const repo = context.repo.repo; | |
| const pr = context.payload.pull_request; | |
| const prNumber = pr.number; | |
| const allowedLabels = new Set(["BCOS-L1", "BCOS-L2", "bcos:l1", "bcos:l2"]); | |
| const labels = (pr.labels || []).map(l => l.name); | |
| const hasTier = labels.some(l => allowedLabels.has(l)); | |
| // Fetch file list (paginated) | |
| const files = []; | |
| for await (const resp of github.paginate.iterator( | |
| github.rest.pulls.listFiles, | |
| { owner, repo, pull_number: prNumber, per_page: 100 } | |
| )) { | |
| for (const f of resp.data) files.push(f.filename); | |
| } | |
| function isDocOnly(path) { | |
| const p = path.toLowerCase(); | |
| if (p.startsWith("docs/")) return true; | |
| if (p.endsWith(".md")) return true; | |
| if (p.endsWith(".png") || p.endsWith(".jpg") || p.endsWith(".jpeg") || p.endsWith(".gif") || p.endsWith(".svg")) return true; | |
| if (p.endsWith(".pdf")) return true; | |
| return false; | |
| } | |
| const nonDoc = files.filter(f => !isDocOnly(f)); | |
| if (nonDoc.length === 0) { | |
| core.info("Doc-only PR: tier label not required."); | |
| return; | |
| } | |
| if (!hasTier) { | |
| core.warning( | |
| "No BCOS tier label found - defaulting to L1. Maintainers: add BCOS-L1 or BCOS-L2 label for explicit tier classification." | |
| ); | |
| core.info("Proceeding with default L1 tier."); | |
| } else { | |
| core.info(`Tier label present: ${labels.join(", ")}`); | |
| } | |
| spdx-and-sbom: | |
| name: SPDX + SBOM Artifacts | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.11" | |
| - name: Install tooling (venv) | |
| run: | | |
| python -m venv .venv-bcos | |
| . .venv-bcos/bin/activate | |
| python -m pip install --upgrade pip | |
| python -m pip install cyclonedx-bom pip-licenses | |
| - name: SPDX check (new files) | |
| continue-on-error: true | |
| run: | | |
| . .venv-bcos/bin/activate | |
| python tools/bcos_spdx_check.py --base-ref "origin/${{ github.base_ref }}" || echo "SPDX check found issues (non-blocking warning)" | |
| - name: Generate SBOM (environment) | |
| continue-on-error: true | |
| run: | | |
| . .venv-bcos/bin/activate | |
| mkdir -p artifacts | |
| python -m cyclonedx_py environment --output-format JSON -o artifacts/sbom_environment.json | |
| - name: Generate dependency license report | |
| continue-on-error: true | |
| run: | | |
| . .venv-bcos/bin/activate | |
| mkdir -p artifacts | |
| pip-licenses --format=json --with-system --with-license-file --output-file artifacts/pip_licenses.json | |
| - name: Hash artifacts | |
| run: | | |
| mkdir -p artifacts | |
| if ls artifacts/*.json 1>/dev/null 2>&1; then | |
| sha256sum artifacts/* > artifacts/sha256sums.txt | |
| else | |
| echo "No artifacts to hash" > artifacts/sha256sums.txt | |
| fi | |
| - name: Generate BCOS attestation | |
| uses: actions/github-script@v8 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const pr = context.payload.pull_request || null; | |
| const prNumber = pr ? pr.number : null; | |
| const labels = pr ? (pr.labels || []).map(l => l.name) : []; | |
| const tier = | |
| labels.includes('BCOS-L2') || labels.includes('bcos:l2') ? 'L2' : | |
| labels.includes('BCOS-L1') || labels.includes('bcos:l1') ? 'L1' : | |
| 'L1'; | |
| const att = { | |
| schema: 'bcos-attestation/v0', | |
| repo: `${context.repo.owner}/${context.repo.repo}`, | |
| pr_number: prNumber, | |
| tier: tier, | |
| labels: labels, | |
| head_sha: context.sha, | |
| base_ref: context.payload.pull_request ? context.payload.pull_request.base.ref : context.ref, | |
| head_ref: context.payload.pull_request ? context.payload.pull_request.head.ref : context.ref, | |
| actor: context.actor, | |
| event: context.eventName, | |
| run: { | |
| id: process.env.GITHUB_RUN_ID, | |
| attempt: process.env.GITHUB_RUN_ATTEMPT, | |
| workflow: process.env.GITHUB_WORKFLOW, | |
| job: process.env.GITHUB_JOB, | |
| url: `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${process.env.GITHUB_RUN_ID}`, | |
| }, | |
| artifacts: [ | |
| { path: 'artifacts/sbom_environment.json' }, | |
| { path: 'artifacts/pip_licenses.json' }, | |
| { path: 'artifacts/sha256sums.txt' }, | |
| ], | |
| generated_at: new Date().toISOString(), | |
| }; | |
| fs.mkdirSync('artifacts', { recursive: true }); | |
| fs.writeFileSync('artifacts/bcos-attestation.json', JSON.stringify(att, null, 2)); | |
| - name: Upload BCOS artifacts | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: bcos-artifacts | |
| path: artifacts/ |