Skip to content
Latchkey

CI workflow (google/guava)

The CI workflow from google/guava, explained and optimized by Latchkey.

A

CI health: A - excellent

Point runs-on at Latchkey and get 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/guava.github/workflows/ci.ymlLicense Apache-2.0View source

What it does

This is the CI workflow from the google/guava 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: CI

on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - master

permissions:
  contents: read

# Cancel in-progress runs for pull requests, but not for master branch pushes
concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
  cancel-in-progress: true

jobs:
  test:
    name: "${{ matrix.root-pom }} on JDK ${{ matrix.java }} on ${{ matrix.os }}"
    strategy:
      matrix:
        os: [ ubuntu-latest ]
        java: [ 8, 11, 17, 25 ]
        root-pom: [ 'pom.xml', 'android/pom.xml' ]
        include:
          - os: windows-latest
            java: 25
            root-pom: pom.xml
    runs-on: ${{ matrix.os }}
    env:
      ROOT_POM: ${{ matrix.root-pom }}
    steps:
      - name: 'Check out repository'
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
      # When we specify multiple JDKs, the final one becomes the default, which is used to execute Maven itself.
      # Our Maven configuration then specifies different JDKs to use for some of the steps:
      # - 11 (sometimes) to *download* to support anyone who runs JDiff or our Gradle integration tests (including our doc snapshots and our Java 11 CI test run) but not to use directly
      # - 26 for running Javadoc and javac (to help people who build Guava locally and might not use a recent JDK to run Maven)
      - name: 'Set up JDKs'
        uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0
        with:
          java-version: |
            ${{ matrix.java }}
            26
          distribution: 'temurin'
          cache: 'maven'
      - name: 'Install'
        shell: bash
        run: ./mvnw -B -ntp -Dtoolchain.skip install -U -DskipTests=true -f $ROOT_POM
      - name: 'Test'
        shell: bash
        run: ./mvnw -B -ntp -P!standard-with-extra-repos -Dtoolchain.skip verify -U -Dmaven.javadoc.skip=true -Dsurefire.toolchain.version=${{ matrix.java }} -f $ROOT_POM
      - name: 'Print Surefire reports'
        # Note: Normally a step won't run if the job has failed, but this causes it to
        if: ${{ failure() }}
        shell: bash
        run: ./util/print_surefire_reports.sh

  gradle-test:
    name: "Gradle Integration Tests"
    runs-on: ubuntu-latest
    steps:
      - name: 'Check out repository'
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
      - name: 'Set up JDKs'
        uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0
        # For the usage of the JDK 11+17, see util/gradle_integration_tests.sh
        # And 26 is for running javac (as configured in the Maven build), as usual.
        with:
          java-version: |
            11
            17
            26
          distribution: 'temurin'
          cache: 'maven'
      - name: 'Set up Gradle'
        uses: gradle/actions/setup-gradle@3f131e8634966bd73d06cc69884922b02e6faf92 # v6.2.0
      - name: 'Integration Test'
        shell: bash
        run: util/gradle_integration_tests.sh

  publish_snapshot:
    name: 'Publish snapshot'
    needs: [ test, gradle-test ]
    if: github.event_name == 'push' && github.repository == 'google/guava'
    runs-on: ubuntu-latest
    steps:
      - name: 'Check out repository'
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
      - name: 'Set up JDKs'
        uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0
        with:
          # For discussion, see the first setup-java block.
          # The publish-snapshot workflow doesn't run tests, so we don't have to care which version Maven would select for that step.
          java-version: 26
          distribution: 'temurin'
          cache: 'maven'
          server-id: central
          server-username: CI_DEPLOY_USERNAME
          server-password: CI_DEPLOY_PASSWORD
      - name: 'Publish'
        env:
          CI_DEPLOY_USERNAME: ${{ secrets.CI_DEPLOY_USERNAME }}
          CI_DEPLOY_PASSWORD: ${{ secrets.CI_DEPLOY_PASSWORD }}
        run: ./util/deploy_snapshot.sh

  generate_docs:
    permissions:
      contents: write
    name: 'Generate latest docs'
    needs: [ test, gradle-test ]
    if: github.event_name == 'push' && github.repository == 'google/guava'
    runs-on: ubuntu-latest
    steps:
      - name: 'Check out repository'
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
      - name: 'Set up JDKs'
        uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0
        with:
          # For discussion, see the first setup-java block.
          # The generate-docs workflow doesn't run tests, so we don't have to care which version Maven would select for that step.
          # But we need Java 11 for JDiff.
          java-version: |
            11
            26
          distribution: 'temurin'
          cache: 'maven'
      - name: 'Generate latest docs'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: ./util/update_snapshot_docs.sh

The same workflow, on Latchkey

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

name: CI
 
on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - master
 
permissions:
  contents: read
 
# Cancel in-progress runs for pull requests, but not for master branch pushes
concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
  cancel-in-progress: true
 
jobs:
  test:
    timeout-minutes: 30
    name: "${{ matrix.root-pom }} on JDK ${{ matrix.java }} on ${{ matrix.os }}"
    strategy:
      matrix:
        os: [ ubuntu-latest ]
        java: [ 8, 11, 17, 25 ]
        root-pom: [ 'pom.xml', 'android/pom.xml' ]
        include:
          - os: windows-latest
            java: 25
            root-pom: pom.xml
    runs-on: ${{ matrix.os }}
    env:
      ROOT_POM: ${{ matrix.root-pom }}
    steps:
      - name: 'Check out repository'
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
      # When we specify multiple JDKs, the final one becomes the default, which is used to execute Maven itself.
      # Our Maven configuration then specifies different JDKs to use for some of the steps:
      # - 11 (sometimes) to *download* to support anyone who runs JDiff or our Gradle integration tests (including our doc snapshots and our Java 11 CI test run) but not to use directly
      # - 26 for running Javadoc and javac (to help people who build Guava locally and might not use a recent JDK to run Maven)
      - name: 'Set up JDKs'
        uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0
        with:
          java-version: |
            ${{ matrix.java }}
            26
          distribution: 'temurin'
          cache: 'maven'
      - name: 'Install'
        shell: bash
        run: ./mvnw -B -ntp -Dtoolchain.skip install -U -DskipTests=true -f $ROOT_POM
      - name: 'Test'
        shell: bash
        run: ./mvnw -B -ntp -P!standard-with-extra-repos -Dtoolchain.skip verify -U -Dmaven.javadoc.skip=true -Dsurefire.toolchain.version=${{ matrix.java }} -f $ROOT_POM
      - name: 'Print Surefire reports'
        # Note: Normally a step won't run if the job has failed, but this causes it to
        if: ${{ failure() }}
        shell: bash
        run: ./util/print_surefire_reports.sh
 
  gradle-test:
    timeout-minutes: 30
    name: "Gradle Integration Tests"
    runs-on: latchkey-small
    steps:
      - name: 'Check out repository'
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
      - name: 'Set up JDKs'
        uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0
        # For the usage of the JDK 11+17, see util/gradle_integration_tests.sh
        # And 26 is for running javac (as configured in the Maven build), as usual.
        with:
          java-version: |
            11
            17
            26
          distribution: 'temurin'
          cache: 'maven'
      - name: 'Set up Gradle'
        uses: gradle/actions/setup-gradle@3f131e8634966bd73d06cc69884922b02e6faf92 # v6.2.0
      - name: 'Integration Test'
        shell: bash
        run: util/gradle_integration_tests.sh
 
  publish_snapshot:
    timeout-minutes: 30
    name: 'Publish snapshot'
    needs: [ test, gradle-test ]
    if: github.event_name == 'push' && github.repository == 'google/guava'
    runs-on: latchkey-small
    steps:
      - name: 'Check out repository'
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
      - name: 'Set up JDKs'
        uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0
        with:
          # For discussion, see the first setup-java block.
          # The publish-snapshot workflow doesn't run tests, so we don't have to care which version Maven would select for that step.
          java-version: 26
          distribution: 'temurin'
          cache: 'maven'
          server-id: central
          server-username: CI_DEPLOY_USERNAME
          server-password: CI_DEPLOY_PASSWORD
      - name: 'Publish'
        env:
          CI_DEPLOY_USERNAME: ${{ secrets.CI_DEPLOY_USERNAME }}
          CI_DEPLOY_PASSWORD: ${{ secrets.CI_DEPLOY_PASSWORD }}
        run: ./util/deploy_snapshot.sh
 
  generate_docs:
    timeout-minutes: 30
    permissions:
      contents: write
    name: 'Generate latest docs'
    needs: [ test, gradle-test ]
    if: github.event_name == 'push' && github.repository == 'google/guava'
    runs-on: latchkey-small
    steps:
      - name: 'Check out repository'
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
      - name: 'Set up JDKs'
        uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0
        with:
          # For discussion, see the first setup-java block.
          # The generate-docs workflow doesn't run tests, so we don't have to care which version Maven would select for that step.
          # But we need Java 11 for JDiff.
          java-version: |
            11
            26
          distribution: 'temurin'
          cache: 'maven'
      - name: 'Generate latest docs'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: ./util/update_snapshot_docs.sh
 

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 (11 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