From 7d51d6acdb0a0c5992428fd81f00c94e6bbc2e1f Mon Sep 17 00:00:00 2001 From: David Gamez Diaz <1192523+davidgamez@users.noreply.github.com> Date: Thu, 25 Jun 2026 13:14:22 -0400 Subject: [PATCH] add maven profile to compile snapshot validator version --- .github/workflows/docker.yml | 67 ++++++++++++++++++++++++++---------- Dockerfile | 9 +++-- README.md | 46 +++++++++++++++++++++++-- pom.xml | 35 ++++++++++++++++++- 4 files changed, 134 insertions(+), 23 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 4d77121..739aa79 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -19,15 +19,58 @@ env: jobs: docker: - name: Build and publish Docker image + name: Build and publish Docker image (${{ matrix.variant }}) runs-on: ubuntu-24.04 permissions: contents: read packages: write + strategy: + fail-fast: false + matrix: + include: + # Stable: default build, gets the moving `latest` tag. + - variant: stable + maven_profiles: "" + latest: "true" + # Snapshot: built against the validator core SNAPSHOT. Never `latest`. + - variant: snapshot + maven_profiles: "snapshot" + latest: "false" steps: - uses: actions/checkout@v7 with: fetch-depth: 0 + + # Derive the API version and the validator core version (honouring the + # matrix Maven profiles) straight from pom.xml so image tags can never + # drift from the actual build. Image name is lower-cased for GHCR. + - name: Compute image tags + id: tags + run: | + set -euo pipefail + PROFILE_ARG="" + if [ -n "${{ matrix.maven_profiles }}" ]; then + PROFILE_ARG="-P${{ matrix.maven_profiles }}" + fi + API_VERSION=$(mvn -q -N $PROFILE_ARG help:evaluate -Dexpression=project.version -DforceStdout) + VALIDATOR_VERSION=$(mvn -q -N $PROFILE_ARG help:evaluate -Dexpression=gtfs-validator.version -DforceStdout) + IMAGE=$(echo "${REGISTRY}/${IMAGE_NAME}" | tr '[:upper:]' '[:lower:]') + # Self-documenting tag: -validator. + # The `validator` infix scopes the trailing version to the validator + # core, not the API (the two versions evolve independently). + DUAL_TAG="${IMAGE}:${API_VERSION}-validator${VALIDATOR_VERSION}" + TAGS="${DUAL_TAG}" + if [ "${{ matrix.latest }}" = "true" ]; then + TAGS="${TAGS}"$'\n'"${IMAGE}:latest" + fi + { + echo "tags<> "$GITHUB_OUTPUT" + echo "Resolved tags:" + echo "${TAGS}" + - name: Set up QEMU uses: docker/setup-qemu-action@v4 - name: Set up Docker Buildx @@ -41,26 +84,14 @@ jobs: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Extract Docker metadata - id: meta - uses: docker/metadata-action@v6 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - tags: | - type=ref,event=branch - type=ref,event=pr - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=semver,pattern={{major}} - type=raw,value=latest,enable={{is_default_branch}} - type=sha - name: Build and push Docker image uses: docker/build-push-action@v7 with: context: . + build-args: | + MAVEN_PROFILES=${{ matrix.maven_profiles }} platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha - cache-to: type=gha,mode=max + tags: ${{ steps.tags.outputs.tags }} + cache-from: type=gha,scope=${{ matrix.variant }} + cache-to: type=gha,mode=max,scope=${{ matrix.variant }} diff --git a/Dockerfile b/Dockerfile index f15caf0..836d75e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,15 +4,20 @@ FROM maven:3.9-eclipse-temurin-17 AS build WORKDIR /workspace +# Optional comma-separated Maven profiles to activate (e.g. "snapshot" to build +# against a pre-release SNAPSHOT of the GTFS validator core). Empty by default, +# which produces a stable build. +ARG MAVEN_PROFILES="" + # Cache dependencies first. COPY pom.xml . COPY .openapi-generator-ignore . -RUN mvn -B -q dependency:go-offline +RUN mvn -B -q ${MAVEN_PROFILES:+-P}${MAVEN_PROFILES} dependency:go-offline # Build the application. COPY src ./src COPY docs ./docs -RUN mvn -B -q clean package -DskipTests +RUN mvn -B -q ${MAVEN_PROFILES:+-P}${MAVEN_PROFILES} clean package -DskipTests # --- Runtime stage ----------------------------------------------------------- FROM eclipse-temurin:17-jre diff --git a/README.md b/README.md index 8518624..67b692c 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,26 @@ mvn test # run the integration tests only mvn verify # also runs the spotless code-style check ``` +### Building against a validator SNAPSHOT + +The default build uses the stable validator core release (`gtfs-validator.version`, +currently `8.0.1`). To build against a pre-release **SNAPSHOT** of the validator +core instead, activate the opt-in `snapshot` profile: + +```bash +mvn -Psnapshot clean package # uses the pinned snapshot (8.0.2-SNAPSHOT) + +# override the snapshot version explicitly: +mvn -Psnapshot -Dgtfs-validator.version=8.0.2-SNAPSHOT clean package +``` + +The profile enables the public [Maven Central snapshot repository][central-snapshots] +(no credentials needed) — required because Maven only resolves `-SNAPSHOT` +artifacts from repositories that explicitly enable snapshots. The API's own +version is unaffected; only the validator core dependency changes. + +[central-snapshots]: https://central.sonatype.com/repository/maven-snapshots/ + ## Code style Matches the [gtfs-validator](https://github.com/MobilityData/gtfs-validator) repo: @@ -102,14 +122,36 @@ docker run --rm -p 8080:8080 gtfs-validator-api:1.0.0 Pass JVM options via `JAVA_OPTS`, e.g. `-e JAVA_OPTS="-Xmx4g"`. +To build an image against a validator-core SNAPSHOT, pass the `MAVEN_PROFILES` +build arg: + +```bash +docker build --build-arg MAVEN_PROFILES=snapshot -t gtfs-validator-api:snapshot . +``` + ### Pre-built image CI publishes multi-arch images (`linux/amd64`, `linux/arm64`) to the GitHub -Container Registry on every push to the default branch and on version tags: +Container Registry on every push to the default branch and on version tags. Two +variants are published: + +| Variant | Tags | Validator core | +|---------|------|----------------| +| Stable | `latest`, `1.0.0-validator8.0.1` | stable release | +| Snapshot | `1.0.0-validator8.0.2-SNAPSHOT` | pre-release SNAPSHOT | + +The tag format is `-validator`: the `validator` +infix scopes the trailing version to the validator **core**, not the API (the two +versions evolve independently). `latest` always points at the stable variant; the +snapshot image is never tagged `latest`. ```bash +# Stable docker pull ghcr.io/mobilitydata/gtfs-validator-api:latest docker run --rm -p 8080:8080 ghcr.io/mobilitydata/gtfs-validator-api:latest + +# Snapshot (built against the validator core SNAPSHOT) +docker pull ghcr.io/mobilitydata/gtfs-validator-api:1.0.0-validator8.0.2-SNAPSHOT ``` ## Continuous integration @@ -119,7 +161,7 @@ GitHub Actions workflows live in `.github/workflows/`: | Workflow | Trigger | Purpose | |----------|---------|---------| | `build.yml` | push / PR to `main`/`master`, manual | `mvn clean verify` — OpenAPI generation, compile, integration tests and the Spotless code-style check; uploads the built jar. | -| `docker.yml` | push / PR / tag `v*` / release, manual | Builds the Docker image (multi-arch). On non-PR events it pushes to `ghcr.io//gtfs-validator-api` with branch, `latest`, semver and commit-SHA tags. | +| `docker.yml` | push / PR / tag `v*` / release, manual | Builds two image variants (stable and validator-SNAPSHOT) via a matrix, multi-arch. On non-PR events it pushes to `ghcr.io//gtfs-validator-api`; stable gets `latest` + `-validator`, snapshot gets `-validator` only. PRs build both but push neither. | ## Configuration diff --git a/pom.xml b/pom.xml index f639e52..0eb08cc 100644 --- a/pom.xml +++ b/pom.xml @@ -50,7 +50,10 @@ 0.2.10 3.0.0 - + 8.0.1 @@ -294,4 +297,34 @@ + + + + + snapshot + + 8.0.2-SNAPSHOT + + + + central-snapshots + Maven Central Snapshots + https://central.sonatype.com/repository/maven-snapshots/ + + false + + + true + + + + +