From 5f66d8461da65d37264b71e66ba006746de92452 Mon Sep 17 00:00:00 2001 From: sshevchenko Date: Mon, 24 Aug 2026 00:57:45 +0200 Subject: [PATCH] Add dependency-graph audit, require contents write --- .github/workflows/dependency-graph-audit.yml | 40 ++++++++++++++++++++ README.md | 17 ++++++++- 2 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/dependency-graph-audit.yml diff --git a/.github/workflows/dependency-graph-audit.yml b/.github/workflows/dependency-graph-audit.yml new file mode 100644 index 0000000..b3e8e31 --- /dev/null +++ b/.github/workflows/dependency-graph-audit.yml @@ -0,0 +1,40 @@ +# Weekly check that every sbt repository in the organization carries the dependency-graph caller +# workflow. A repo without it submits no dependency graph, gets no Dependabot alerts and looks +# falsely clean. The default token only sees public repositories; add a read-only ORG_AUDIT_TOKEN +# secret to include private ones. +name: Dependency graph audit + +on: + schedule: + - cron: '0 6 * * 1' + workflow_dispatch: + +permissions: {} + +jobs: + audit: + runs-on: ubuntu-latest + + steps: + - name: find sbt repos missing the workflow + env: + GH_TOKEN: ${{ secrets.ORG_AUDIT_TOKEN || github.token }} + run: | + missing=() + while read -r repo; do + gh api "repos/$repo/contents/build.sbt" --silent 2>/dev/null || continue + gh api "repos/$repo/contents/.github/workflows/dependency-graph.yml" --silent 2>/dev/null && continue + missing+=("$repo") + done < <(gh repo list "$GITHUB_REPOSITORY_OWNER" --no-archived --limit 1000 \ + --json nameWithOwner,primaryLanguage \ + --jq '.[] | select(.primaryLanguage.name == "Scala") | .nameWithOwner') + { + echo "## Dependency graph audit" + if [ ${#missing[@]} -eq 0 ]; then + echo "Every sbt repository submits its dependency graph." + else + echo "Repositories without \`.github/workflows/dependency-graph.yml\`:" + printf -- '- %s\n' "${missing[@]}" + fi + } >> "$GITHUB_STEP_SUMMARY" + [ ${#missing[@]} -eq 0 ] diff --git a/README.md b/README.md index ad6bde3..1439dd0 100644 --- a/README.md +++ b/README.md @@ -138,13 +138,23 @@ on: push: branches: [ master ] +permissions: + contents: write + jobs: submit: - uses: evolution-gaming/scala-github-actions/.github/workflows/dependency-graph.yml@ # v6.2.0 + uses: evolution-gaming/scala-github-actions/.github/workflows/dependency-graph.yml@ # v6.4.0 ``` Resolve `` the same way as for the CI workflow above. +The `permissions` block is required. A called workflow can only downgrade the caller's token, never +raise it, so on a repository whose default workflow permissions are read-only the submission fails +without it. + +A scheduled [audit workflow](.github/workflows/dependency-graph-audit.yml) in this repository lists +the organization's sbt repos that are missing the caller file and fails while any exist. + ### Inputs | input | default | notes | @@ -158,9 +168,12 @@ Ignore modules that are never published (documentation, integration tests), so t do not generate alerts for artifacts nobody consumes: ```yaml +permissions: + contents: write + jobs: submit: - uses: evolution-gaming/scala-github-actions/.github/workflows/dependency-graph.yml@ # v6.2.0 + uses: evolution-gaming/scala-github-actions/.github/workflows/dependency-graph.yml@ # v6.4.0 with: modules_ignore: 'docs_2.13 docs_3 foo-it-tests_2.13 foo-it-tests_3' ```