Skip to content
Latchkey

Build workflow (google/gson)

The Build workflow from google/gson, explained and optimized by Latchkey.

C

CI health: C - fair

Point runs-on at Latchkey and get run de-duplication, job timeouts, self-healing for flaky steps, and up to 58% lower cost, applied automatically.

Grade your own workflow free or run it on Latchkey →
Source: google/gson.github/workflows/build.ymlLicense Apache-2.0View source

What it does

This is the Build workflow from the google/gson repository, a real project running GitHub Actions. It is shown here with attribution under its Apache-2.0 license.

Below, Latchkey shows a faster, safer version produced by its optimization engine.

The workflow

workflow (.yml)
name: Build

on:
  push:
    branches-ignore:
      # Ignore Dependabot branches because it will also open a pull request, which would cause the
      # workflow to redundantly run twice
      - dependabot/**
  pull_request:

permissions:
  contents: read #  to fetch code (actions/checkout)

env:
  # Common Maven arguments
  MAVEN_ARGS: --show-version --batch-mode --no-transfer-progress

jobs:
  build:
    name: "Build on JDK ${{ matrix.java }}"
    strategy:
      matrix:
        java: [ 17, 21 ]
        include:
          # Custom JDK 11 configuration because some of the plugins and test dependencies don't support it anymore,
          # but it is important to still test with a JDK version without Record classes
          - java: 11
            # Disable Enforcer check which (intentionally) prevents using JDK 11 for building
            # Exclude 'test-graal-native-image' module because JUnit 6 requires >= Java 17
            # Exclude 'proto' module because protobuf-maven-plugin requires >= Java 17
            extra-mvn-args: -Denforcer.fail=false --projects '!test-graal-native-image,!proto'
          - java: 25
            # Disable Enforcer check which (intentionally) prevents using JDK 25 for building
            # Exclude 'test-shrinker' because ProGuard does not support JDK 25 yet, see
            # https://github.com/Guardsquare/proguard/issues/481 and https://github.com/Guardsquare/proguard/issues/473
            # TODO: Once ProGuard supports JDK 25, also remove the corresponding 'JDK25' profile in `gson/pom.xml`
            extra-mvn-args: -Denforcer.fail=false --projects '!test-shrinker'
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd  # v6.0.2
      - name: "Set up JDK ${{ matrix.java }}"
        uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654  # v5.2.0
        with:
          distribution: 'temurin'
          java-version: ${{ matrix.java }}
          cache: 'maven'
      - name: Build with Maven
        # This also runs javadoc:jar to detect any issues with the Javadoc generated during release
        run: mvn verify javadoc:jar ${{ matrix.extra-mvn-args || '' }}

  # Build a subset of the Gson API, see also https://github.com/google/gson/pull/2946
  build-gson-subset:
    name: Build Gson subset
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd  # v6.0.2
      - name: Set up JDK
        uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654  # v5.2.0
        with:
          distribution: 'temurin'
          java-version: 21
          cache: 'maven'
      - name: Build with Maven
        run: mvn clean test --projects gson --activate-profiles gson-subset

  native-image-test:
    name: "GraalVM Native Image test (JDK ${{ matrix.java }})"
    strategy:
      matrix:
        java: [ 21 ]
        include:
          - java: 25
            # Disable Enforcer check which (intentionally) prevents using JDK 25 for building
            # TODO: Remove this once JDK 25 is fully supported for building Gson
            extra-mvn-args: -Denforcer.fail=false
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd  # v6.0.2
      - name: "Set up GraalVM"
        uses: graalvm/setup-graalvm@bef4b0e916c7dd079bf60fb95d49139f67e32c5f  # v1.5.3
        with:
          java-version: ${{ matrix.java }}
          distribution: 'graalvm'
          # According to documentation in graalvm/setup-graalvm this is used to avoid rate-limiting issues
          github-token: ${{ secrets.GITHUB_TOKEN }}
          cache: 'maven'
      - name: Build and run tests
        # Only run tests in `test-graal-native-image` (and implicitly build and run tests in `gson`),
        # everything else is covered already by regular build job above
        run: mvn test --activate-profiles native-image-test --projects test-graal-native-image --also-make ${{ matrix.extra-mvn-args || '' }}

  verify-reproducible-build:
    name: "Verify reproducible build"
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd  # v6.0.2
      - name: Set up JDK
        uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654  # v5.2.0
        with:
          distribution: 'temurin'
          java-version: 17
          cache: 'maven'

      - name: "Verify no plugin issues"
        run: mvn artifact:check-buildplan --projects '!metrics,!test-graal-native-image,!test-jpms,!test-shrinker'

      - name: "Verify reproducible build"
        # See https://maven.apache.org/guides/mini/guide-reproducible-builds.html#how-to-test-my-maven-build-reproducibility
        run: |
          mvn clean install -Dmaven.test.skip --projects '!metrics,!test-graal-native-image,!test-jpms,!test-shrinker'
          # Run with `-Dbuildinfo.attach=false`; otherwise `artifact:compare` fails because it creates a `.buildinfo` file which
          # erroneously references the existing `.buildinfo` file (respectively because it is overwriting it, a file with size 0)
          # See https://issues.apache.org/jira/browse/MARTIFACT-57
          mvn clean verify artifact:compare -Dmaven.test.skip --projects '!metrics,!test-graal-native-image,!test-jpms,!test-shrinker' -Dbuildinfo.attach=false

The same workflow, on Latchkey

Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.

name: Build
 
on:
  push:
    branches-ignore:
      # Ignore Dependabot branches because it will also open a pull request, which would cause the
      # workflow to redundantly run twice
      - dependabot/**
  pull_request:
 
permissions:
  contents: read #  to fetch code (actions/checkout)
 
env:
  # Common Maven arguments
  MAVEN_ARGS: --show-version --batch-mode --no-transfer-progress
 
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
 
jobs:
  build:
    timeout-minutes: 30
    name: "Build on JDK ${{ matrix.java }}"
    strategy:
      matrix:
        java: [ 17, 21 ]
        include:
          # Custom JDK 11 configuration because some of the plugins and test dependencies don't support it anymore,
          # but it is important to still test with a JDK version without Record classes
          - java: 11
            # Disable Enforcer check which (intentionally) prevents using JDK 11 for building
            # Exclude 'test-graal-native-image' module because JUnit 6 requires >= Java 17
            # Exclude 'proto' module because protobuf-maven-plugin requires >= Java 17
            extra-mvn-args: -Denforcer.fail=false --projects '!test-graal-native-image,!proto'
          - java: 25
            # Disable Enforcer check which (intentionally) prevents using JDK 25 for building
            # Exclude 'test-shrinker' because ProGuard does not support JDK 25 yet, see
            # https://github.com/Guardsquare/proguard/issues/481 and https://github.com/Guardsquare/proguard/issues/473
            # TODO: Once ProGuard supports JDK 25, also remove the corresponding 'JDK25' profile in `gson/pom.xml`
            extra-mvn-args: -Denforcer.fail=false --projects '!test-shrinker'
    runs-on: latchkey-small
 
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd  # v6.0.2
      - name: "Set up JDK ${{ matrix.java }}"
        uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654  # v5.2.0
        with:
          distribution: 'temurin'
          java-version: ${{ matrix.java }}
          cache: 'maven'
      - name: Build with Maven
        # This also runs javadoc:jar to detect any issues with the Javadoc generated during release
        run: mvn verify javadoc:jar ${{ matrix.extra-mvn-args || '' }}
 
  # Build a subset of the Gson API, see also https://github.com/google/gson/pull/2946
  build-gson-subset:
    timeout-minutes: 30
    name: Build Gson subset
    runs-on: latchkey-small
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd  # v6.0.2
      - name: Set up JDK
        uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654  # v5.2.0
        with:
          distribution: 'temurin'
          java-version: 21
          cache: 'maven'
      - name: Build with Maven
        run: mvn clean test --projects gson --activate-profiles gson-subset
 
  native-image-test:
    timeout-minutes: 30
    name: "GraalVM Native Image test (JDK ${{ matrix.java }})"
    strategy:
      matrix:
        java: [ 21 ]
        include:
          - java: 25
            # Disable Enforcer check which (intentionally) prevents using JDK 25 for building
            # TODO: Remove this once JDK 25 is fully supported for building Gson
            extra-mvn-args: -Denforcer.fail=false
    runs-on: latchkey-small
 
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd  # v6.0.2
      - name: "Set up GraalVM"
        uses: graalvm/setup-graalvm@bef4b0e916c7dd079bf60fb95d49139f67e32c5f  # v1.5.3
        with:
          java-version: ${{ matrix.java }}
          distribution: 'graalvm'
          # According to documentation in graalvm/setup-graalvm this is used to avoid rate-limiting issues
          github-token: ${{ secrets.GITHUB_TOKEN }}
          cache: 'maven'
      - name: Build and run tests
        # Only run tests in `test-graal-native-image` (and implicitly build and run tests in `gson`),
        # everything else is covered already by regular build job above
        run: mvn test --activate-profiles native-image-test --projects test-graal-native-image --also-make ${{ matrix.extra-mvn-args || '' }}
 
  verify-reproducible-build:
    timeout-minutes: 30
    name: "Verify reproducible build"
    runs-on: latchkey-small
 
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd  # v6.0.2
      - name: Set up JDK
        uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654  # v5.2.0
        with:
          distribution: 'temurin'
          java-version: 17
          cache: 'maven'
 
      - name: "Verify no plugin issues"
        run: mvn artifact:check-buildplan --projects '!metrics,!test-graal-native-image,!test-jpms,!test-shrinker'
 
      - name: "Verify reproducible build"
        # See https://maven.apache.org/guides/mini/guide-reproducible-builds.html#how-to-test-my-maven-build-reproducibility
        run: |
          mvn clean install -Dmaven.test.skip --projects '!metrics,!test-graal-native-image,!test-jpms,!test-shrinker'
          # Run with `-Dbuildinfo.attach=false`; otherwise `artifact:compare` fails because it creates a `.buildinfo` file which
          # erroneously references the existing `.buildinfo` file (respectively because it is overwriting it, a file with size 0)
          # See https://issues.apache.org/jira/browse/MARTIFACT-57
          mvn clean verify artifact:compare -Dmaven.test.skip --projects '!metrics,!test-graal-native-image,!test-jpms,!test-shrinker' -Dbuildinfo.attach=false
 

What changed

What Latchkey heals here

This workflow has steps that commonly fail on transient issues (network, registries, flaky browsers). On Latchkey managed runners they are detected, retried, and self-healed instead of failing your build:

This workflow runs 4 jobs (5 with the matrix expanded) per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.

Actions used in this workflow