Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions .github/renovate.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
"extends": [
"config:recommended",
":semanticCommits",
":dependencyDashboard",
"helpers:pinGitHubActionDigests"
":dependencyDashboard"
],
"timezone": "UTC",
"schedule": [
Expand All @@ -19,15 +18,15 @@
"osvVulnerabilityAlerts": false,
"packageRules": [
{
"description": "The workflows pin every action to a commit SHA, so a floating tag cannot change what CI runs; keep those digests fresh in one PR.",
"description": "The workflows reference actions by their major tag (v7), so the tag itself is what moves and there is no digest to refresh; raise the major bumps in one PR.",
"matchManagers": [
"github-actions"
],
"groupName": "github actions",
"pinDigests": true
"pinDigests": false
},
{
"description": "assembly/Dockerfile pins its base images by digest for the same reason, and a Temurin rebuild is what carries the base OS's security fixes in.",
"description": "assembly/Dockerfile pins its base images by digest, because an image tag is re-pushed in place and the released artifacts are built from it; a Temurin rebuild is what carries the base OS's security fixes in.",
"matchManagers": [
"dockerfile"
],
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/central-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ jobs:
fi
echo "All required Maven Central secrets are present."

- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
- uses: actions/checkout@v7

- name: Derive the reproducible-build timestamp
# The pom declares no project.build.outputTimestamp on purpose, so that no
Expand All @@ -80,16 +80,16 @@ jobs:
echo "BUILD_OUTPUT_TIMESTAMP=${timestamp}" >> "$GITHUB_ENV"

- name: Set up JDK 25
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
uses: actions/setup-java@v6
with:
java-version: '25'
distribution: 'temurin'
cache: maven
# Creates a settings.xml server entry with id "central" whose
# username/password come from the env vars below.
server-id: central
server-username: MAVEN_CENTRAL_USERNAME
server-password: MAVEN_CENTRAL_PASSWORD
server-username-env-var: MAVEN_CENTRAL_USERNAME
server-password-env-var: MAVEN_CENTRAL_PASSWORD

- name: Bootstrap CLAUDE.md enforcer rule
# The custom enforcer rule is consumed as a plugin dependency by the
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,17 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
uses: actions/checkout@v7

- name: Setup java
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
uses: actions/setup-java@v6
with:
java-version: 25
distribution: 'temurin'

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@988661ebb5e81487b3fb31b2185d2856c0a10679 # v4
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
Expand All @@ -66,7 +66,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@988661ebb5e81487b3fb31b2185d2856c0a10679 # v4
uses: github/codeql-action/autobuild@v4

# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
Expand All @@ -80,6 +80,6 @@ jobs:


- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@988661ebb5e81487b3fb31b2185d2856c0a10679 # v4
uses: github/codeql-action/analyze@v4
with:
category: "/language:${{matrix.language}}"
6 changes: 3 additions & 3 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,17 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
- uses: actions/checkout@v7
- name: Set up JDK 25
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
uses: actions/setup-java@v6
with:
java-version: '25'
distribution: 'temurin'
cache: maven
- name: Run tests with JaCoCo
run: mvn -B -ntp verify -Pcoverage --file pom.xml
- name: Upload coverage reports
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
uses: actions/upload-artifact@v7
with:
name: jacoco-reports
path: '**/target/site/jacoco/'
Expand Down
16 changes: 8 additions & 8 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
uses: actions/checkout@v7

- name: Set up JDK 25
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
uses: actions/setup-java@v6
with:
java-version: '25'
distribution: 'temurin'
Expand Down Expand Up @@ -78,17 +78,17 @@ jobs:
} >> "$GITHUB_OUTPUT"

- name: Set up QEMU
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3
uses: docker/setup-qemu-action@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
uses: docker/setup-buildx-action@v4

# A single-arch build first, loaded into the local daemon, so the image is
# actually executed before anything is published. Buildx cannot --load a
# multi-platform image, hence the two builds; the GHA layer cache makes the
# later multi-arch build reuse this work for linux/amd64.
- name: Build the image (linux/amd64)
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
uses: docker/build-push-action@v7
with:
context: .
file: assembly/Dockerfile
Expand Down Expand Up @@ -122,7 +122,7 @@ jobs:
# caught before the push rather than after — and, on the weekly run, while
# there is still time to fix it rather than at the release.
- name: Scan the image for vulnerabilities
uses: aquasecurity/trivy-action@a9c7b0f06e461e9d4b4d1711f154ee024b8d7ab8 # v0.36.0
uses: aquasecurity/trivy-action@v0.36.0
with:
image-ref: tools:ci
format: table
Expand All @@ -132,7 +132,7 @@ jobs:

- name: Log in to GitHub Container Registry
if: github.event_name == 'release'
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
Expand All @@ -143,7 +143,7 @@ jobs:
# architectures the trimmed DuckDB driver still carries natives for.
- name: Push the image to GHCR
if: github.event_name == 'release'
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
uses: docker/build-push-action@v7
with:
context: .
file: assembly/Dockerfile
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
- uses: actions/checkout@v7
- name: Set up JDK 25
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
uses: actions/setup-java@v6
with:
java-version: '25'
distribution: 'temurin'
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/maven-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
packages: write

steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
- uses: actions/checkout@v7

- name: Derive the reproducible-build timestamp
# The pom declares no project.build.outputTimestamp on purpose, so that no
Expand All @@ -43,7 +43,7 @@ jobs:
echo "BUILD_OUTPUT_TIMESTAMP=${timestamp}" >> "$GITHUB_ENV"

- name: Set up JDK 25
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
uses: actions/setup-java@v6
with:
java-version: '25'
distribution: 'temurin'
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/maven-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ jobs:
runs-on: windows-latest

steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
- uses: actions/checkout@v7
- name: Set up JDK 25
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
uses: actions/setup-java@v6
with:
java-version: '25'
distribution: 'temurin'
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
- uses: actions/checkout@v7
- name: Set up JDK 25
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
uses: actions/setup-java@v6
with:
java-version: '25'
distribution: 'temurin'
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/pitest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
- uses: actions/checkout@v7
- name: Set up JDK 25
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
uses: actions/setup-java@v6
with:
java-version: '25'
distribution: 'temurin'
Expand All @@ -40,7 +40,7 @@ jobs:
# bound to the `test` phase, so it still runs on every module.
run: mvn -B -ntp install -Ppitest --file pom.xml
- name: Upload mutation testing reports
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
uses: actions/upload-artifact@v7
with:
name: pitest-reports
path: '**/target/pit-reports/'
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/spotbugs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
- uses: actions/checkout@v7
- name: Set up JDK 25
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
uses: actions/setup-java@v6
with:
java-version: '25'
distribution: 'temurin'
Expand Down Expand Up @@ -66,11 +66,11 @@ jobs:
# No category input: it would only apply to runs that have no
# automationDetails.id of their own, and the step above gives every run
# the per-module id that keeps the delivery's runs distinct.
uses: github/codeql-action/upload-sarif@988661ebb5e81487b3fb31b2185d2856c0a10679 # v4
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: target/sarif
- name: Upload SpotBugs reports
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
uses: actions/upload-artifact@v7
with:
name: spotbugs-reports
path: |
Expand Down
34 changes: 24 additions & 10 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -831,13 +831,24 @@ across all ten, and a new workflow is expected to keep them:
itself at 120 s has no business finishing an answer nobody is waiting for.
Everywhere else it is `false` — a scheduled run is not superseded by a newer
commit, and a publish interrupted half-way can leave a partial release behind.
- **Actions pinned to a commit SHA**, with the tag kept in a trailing comment
(`uses: actions/checkout@d23441a… # v6`). A tag is mutable, so an unpinned
action is a third party's ability to change what CI runs without a commit
here — and CI is what produces the released artifacts the supply-chain posture
of [ADR 0002](docs/adr/0002-security-policy-and-supply-chain-posture.md) rests
on. `assembly/Dockerfile` pins its `eclipse-temurin` base images by digest for
the same reason. Renovate refreshes both.
- **Actions referenced by their major tag alone** — `uses: actions/setup-java@v6`,
never a commit SHA and never `@v6.0.0`. The major tag is the one each action's
maintainers move, so a patch or a security fix inside an action reaches CI
without a commit here, and the workflow says in the line itself what it runs
rather than hiding it behind a digest. The trade is deliberate: a tag is
mutable, so this trusts each action's owner not to re-point it — see the
trade-off recorded in
[ADR 0005](docs/adr/0005-renovate-dependency-updates.md).
`aquasecurity/trivy-action` is the one action that cannot follow the rule: it
publishes no major tag at all — every one of its 75 tags is an exact `v0.x.y`
release — so `docker.yml` names `@v0.36.0` and Renovate bumps it like any other
dependency.
- **`assembly/Dockerfile` is the opposite case and stays pinned by digest.** An
image tag is re-pushed in place by whoever owns it, and those `eclipse-temurin`
base images end up *inside* the released artifacts, which is the part of the
supply-chain posture of
[ADR 0002](docs/adr/0002-security-policy-and-supply-chain-posture.md) that a
mutable base image would undo. Renovate keeps those digests fresh.

### Dependency updates

Expand All @@ -860,9 +871,12 @@ configuration is `.github/renovate.json`:
once already.
- This project's own `io.github.adamw7:**` modules are **disabled**: they resolve
inside the reactor at `${revision}`.
- `pinDigests` is on for the **github-actions** and **dockerfile** managers, so
the SHA pins above are refreshed rather than left to rot; the action bumps
arrive as one grouped PR.
- `pinDigests` is **off** for the **github-actions** manager and **on** for
**dockerfile**, matching the two conventions above: the workflows track major
tags, so there is no action digest to refresh, while the Dockerfile's base
images stay pinned and current. What Renovate still raises for actions is the
major move — `@v7` to `@v8` — as one grouped PR, and that is the one to read
release notes for.
- A **major** bump of the Maven API artifacts or of Spring Boot needs dependency
dashboard approval — a Maven 4 API is wired in on purpose while the build is
pinned to 3.9.x, and the framework the MCP servers boot on deserves a review.
Expand Down
12 changes: 9 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,9 +236,15 @@ the whole matrix passes:
GHCR; `maven-publish.yml` (GitHub Packages); `central-publish.yml` (Maven
Central).

Every workflow builds on JDK 25 (Temurin). Use clear, conventional commit
messages — the `git-commit` skill writes them with this repository's real module
scopes — keep changes focused, and add or update tests alongside the code.
Every workflow builds on JDK 25 (Temurin). Actions are referenced by their
**major tag alone** (`uses: actions/setup-java@v6`) — not a commit SHA, not
`@v6.0.0` — so an action's own patches reach CI without a commit here.
`aquasecurity/trivy-action` publishes no major tag and is the exception, at
`@v0.36.0`. `assembly/Dockerfile` still pins its base images by digest.

Use clear, conventional commit messages — the `git-commit` skill writes them with
this repository's real module scopes — keep changes focused, and add or update
tests alongside the code.
**Do not open a pull request unless explicitly asked.**

## Agent configuration
Expand Down
18 changes: 18 additions & 0 deletions docs/adr/0005-renovate-dependency-updates.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,16 @@ repository's shape calls for:
dashboard rather than arriving unannounced.
- **This project's own `io.github.adamw7` modules disabled** — they resolve inside
the reactor at `${revision}`, so there is no release for Renovate to raise.
- **`pinDigests` off for github-actions, on for dockerfile.** The workflows
reference each action by its major tag (`actions/setup-java@v6`), so the tag is
what moves and there is no digest for Renovate to refresh; what it raises is
the major bump, `@v6` to `@v7`, in the grouped actions pull request — the one
place release notes are worth reading. The Dockerfile is the opposite case and
stays pinned: an image tag is re-pushed in place by whoever owns it, and those
base images end up inside the released artifacts.
`aquasecurity/trivy-action` publishes no major tag at all — every one of its 75
tags is an exact `v0.x.y` release — so it is referenced exactly and Renovate
raises its minor bumps like any other dependency.

Validate a change to that file with
`npx --package renovate renovate-config-validator` before committing it.
Expand All @@ -93,3 +103,11 @@ Validate a change to that file with
- Requires the Renovate App to be installed and configured on the repository.
- Care is needed so Renovate and Dependabot do not both open a PR for the same
security-driven bump; the role split in ADR 0002 exists to prevent that.
- Referencing actions by a major tag rather than a commit SHA means a tag that is
re-pointed — by a compromised account or by its owner — changes what CI runs
without a commit in this repository. That is accepted knowingly: it is what
lets an action's own patch and security releases reach CI unattended, the
actions in use are first-party GitHub and Docker ones plus Trivy, and the
artifacts a release actually ships are protected at the layer that survives
this — `assembly/Dockerfile`'s digest-pinned base images. Revisit it if an
action in use changes hands.
Loading