From 070fd794a5578c82d9a3a861965210b4f701b1f3 Mon Sep 17 00:00:00 2001 From: Denis_Drobyshev Date: Wed, 5 Aug 2026 17:22:40 +0300 Subject: [PATCH] Scan the one executable file on the site, and add the rest assets/site.js is 3 KB with no dependencies and no build step - exactly the kind of file that quietly accumulates an innerHTML assignment nobody reviews, because there is no review surface around it. Dependabot watches actions and nothing else. There is no package manifest here, and adding one to give it something to do would undo the property check_site.py exists to enforce: the site makes no third-party requests. The aggregate CI job looks redundant with one job. That is the point - a second job added later is covered without anyone remembering to edit the branch protection rule. --- .github/dependabot.yml | 18 +++++++++ .github/workflows/ci.yml | 21 +++++++++- .github/workflows/codeql.yml | 39 ++++++++++++++++++ .github/workflows/dependabot-auto-merge.yml | 44 +++++++++++++++++++++ .github/workflows/external-links.yml | 2 +- 5 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/codeql.yml create mode 100644 .github/workflows/dependabot-auto-merge.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..d3aaaeb --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,18 @@ +version: 2 + +# Actions only. The site is hand-written HTML, CSS and one 3 KB script with no +# build step and no third-party requests — there is no package manifest here for +# Dependabot to read, and adding one to give it something to do would undo the +# property `scripts/check_site.py` exists to enforce. +updates: + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: weekly + day: monday + commit-message: + prefix: "ci" + groups: + actions: + patterns: ["*"] + open-pull-requests-limit: 5 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2a0e472..40a2bc8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,9 +18,9 @@ jobs: name: Site checks runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v7 with: python-version: "3.12" @@ -31,3 +31,20 @@ jobs: - name: Check the sitemap is well-formed run: python -c "import xml.dom.minidom, sys; xml.dom.minidom.parse('sitemap.xml'); print('sitemap.xml parses')" + + ci: + name: CI + runs-on: ubuntu-latest + if: always() + needs: [site] + steps: + # One aggregate check to require in branch protection. There is one job + # today, and this is what keeps that from mattering: a second job added + # later is covered without touching the protection rule. + - name: Fail if any job did not succeed + if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') + run: | + echo "One or more jobs failed:" + echo '${{ toJSON(needs) }}' + exit 1 + - run: echo "All checks passed." diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..e299c3a --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,39 @@ +name: CodeQL + +on: + push: + branches: [main] + pull_request: + branches: [main] + schedule: + # Weekly, because advisories land between pushes: a rule added after the + # last commit would otherwise never run against this code. + - cron: "47 5 * * 1" + workflow_dispatch: + +permissions: + contents: read + +jobs: + analyze: + name: Analyze JavaScript + runs-on: ubuntu-latest + permissions: + security-events: write + actions: read + contents: read + steps: + - uses: actions/checkout@v7 + + - uses: github/codeql-action/init@v4 + with: + # `assets/site.js` is the only executable thing on the site: 3 KB, no + # dependencies, no build step. That is exactly the kind of file that + # accumulates an innerHTML assignment nobody reviews, which is what + # the default query pack is good at finding. + languages: javascript-typescript + queries: security-and-quality + + - uses: github/codeql-action/analyze@v4 + with: + category: "/language:javascript-typescript" diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml new file mode 100644 index 0000000..2c627ba --- /dev/null +++ b/.github/workflows/dependabot-auto-merge.yml @@ -0,0 +1,44 @@ +name: Dependabot auto-merge + +# Actions are the only ecosystem Dependabot watches here, and an action bump is +# the update that piles up unread until the queue is too long to review +# honestly. Auto-merge is queued, not immediate: GitHub still waits for the +# required checks, and `scripts/check_site.py` is what those checks run. + +on: pull_request_target + +permissions: + contents: read + +jobs: + auto-merge: + if: github.actor == 'dependabot[bot]' + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + steps: + # Reads the update type from the PR that Dependabot opened. Nothing from + # the branch is checked out or executed, which is what makes + # pull_request_target safe to use here. + - id: metadata + uses: dependabot/fetch-metadata@v2 + + - name: Approve and queue the merge + if: >- + steps.metadata.outputs.package-ecosystem == 'github_actions' || + steps.metadata.outputs.update-type == 'version-update:semver-patch' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR: ${{ github.event.pull_request.html_url }} + run: | + gh pr review --approve "$PR" + gh pr merge --auto --squash "$PR" + + - name: Explain why this one was left alone + if: >- + steps.metadata.outputs.package-ecosystem != 'github_actions' && + steps.metadata.outputs.update-type != 'version-update:semver-patch' + env: + TYPE: ${{ steps.metadata.outputs.update-type }} + run: echo "$TYPE is not auto-merged; this pull request needs a human." diff --git a/.github/workflows/external-links.yml b/.github/workflows/external-links.yml index 8c70449..04d615f 100644 --- a/.github/workflows/external-links.yml +++ b/.github/workflows/external-links.yml @@ -16,7 +16,7 @@ jobs: name: Check outbound links runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - name: Run lychee id: lychee