Skip to content
Latchkey

Make Linux Plugin workflow (grpc/grpc-web)

The Make Linux Plugin workflow from grpc/grpc-web, explained and optimized by Latchkey.

C

CI health: C - fair

Run this on Latchkey for self-healing, caching, and up to 58% lower cost.

Grade your own workflow free or run it on Latchkey →
Source: grpc/grpc-web.github/workflows/make-plugin-linux.ymlLicense Apache-2.0View source

What it does

This is the Make Linux Plugin workflow from the grpc/grpc-web 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: Make Linux Plugin

on:
  push:
    paths:
      - .github/workflows/make-plugin-linux.yml
  pull_request:
    paths:
      - .github/workflows/make-plugin-linux.yml
  workflow_dispatch:
    inputs:
      version_number:
        description: 'Version number'
        required: true
        default: '2.x.x'

jobs:
  build:
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-22.04, ubuntu-22.04-arm]
    runs-on: ${{ matrix.os }}
    steps:
    - uses: actions/checkout@v4
    - name: Compute VERSION_NUMBER
      run: |
        INPUT_VERSION="${{ github.event.inputs.version_number }}"
        if [ -n "$INPUT_VERSION" ]; then
          VERSION="$INPUT_VERSION"
        else
          VERSION="$GITHUB_REF_NAME"
        fi
        VERSION="${VERSION//\//-}"
        echo "VERSION_NUMBER=$VERSION" >> "$GITHUB_ENV"
        echo "Computed VERSION_NUMBER=$VERSION"
    - name: Compute ARCH suffix and artifact name
      id: meta
      run: |
        ARCH=$(uname -m)
        case "$ARCH" in
          aarch64|arm64)
            ARCH_SUFFIX="aarch64"
            ;;
          x86_64|amd64)
            ARCH_SUFFIX="x86_64"
            ;;
          *)
            echo "Unsupported architecture: $ARCH" >&2
            exit 1
            ;;
        esac
        ARTIFACT="protoc-gen-grpc-web-${VERSION_NUMBER}-linux-${ARCH_SUFFIX}"
        echo "ARTIFACT=$ARTIFACT" >> "$GITHUB_ENV"
        echo "artifact=$ARTIFACT" >> "$GITHUB_OUTPUT"
        echo "Will produce artifact: $ARTIFACT"
    - name: Install Bazelisk (Bazel)
      run: |
        sudo apt-get update
        sudo apt-get install -y unzip zip
        ARCH=$(uname -m)
        case "$ARCH" in
          aarch64|arm64)
            BAZELISK_URL="https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-arm64"
            ;;
          x86_64|amd64)
            BAZELISK_URL="https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-amd64"
            ;;
          *)
            echo "Unsupported architecture for Bazelisk: $ARCH" >&2
            exit 1
            ;;
        esac
        echo "Downloading Bazelisk from $BAZELISK_URL"
        sudo curl -L -o /usr/local/bin/bazelisk "$BAZELISK_URL"
        sudo chmod +x /usr/local/bin/bazelisk
        # Also provide `bazel` symlink for tools that expect it
        sudo ln -sf /usr/local/bin/bazelisk /usr/local/bin/bazel
        bazelisk version
    - name: Build protoc-gen-grpc-web with Bazel (older glibc baseline)
      run: |
        # Partially static link libstdc++/libgcc to reduce GLIBCXX constraints
        bazelisk build \
          --linkopt=-static-libstdc++ \
          --linkopt=-static-libgcc \
          //javascript/net/grpc/web/generator:protoc-gen-grpc-web
    - name: Move artifact
      run: |
        mv bazel-bin/javascript/net/grpc/web/generator/protoc-gen-grpc-web \
          ./${ARTIFACT}
    - name: Generate sha256
      run: |
        openssl dgst -sha256 -r -out ${ARTIFACT}.sha256 \
          ${ARTIFACT}
    - name: Verify sha256
      run: sha256sum -c ${ARTIFACT}.sha256
    - name: Upload artifacts
      uses: actions/upload-artifact@v4
      with:
        name: ${{ steps.meta.outputs.artifact }}
        path: protoc-gen-grpc-web*

The same workflow, on Latchkey

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

name: Make Linux Plugin
 
on:
  push:
    paths:
      - .github/workflows/make-plugin-linux.yml
  pull_request:
    paths:
      - .github/workflows/make-plugin-linux.yml
  workflow_dispatch:
    inputs:
      version_number:
        description: 'Version number'
        required: true
        default: '2.x.x'
 
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
 
jobs:
  build:
    timeout-minutes: 30
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-22.04, ubuntu-22.04-arm]
    runs-on: ${{ matrix.os }}
    steps:
    - uses: actions/checkout@v4
    - name: Compute VERSION_NUMBER
      run: |
        INPUT_VERSION="${{ github.event.inputs.version_number }}"
        if [ -n "$INPUT_VERSION" ]; then
          VERSION="$INPUT_VERSION"
        else
          VERSION="$GITHUB_REF_NAME"
        fi
        VERSION="${VERSION//\//-}"
        echo "VERSION_NUMBER=$VERSION" >> "$GITHUB_ENV"
        echo "Computed VERSION_NUMBER=$VERSION"
    - name: Compute ARCH suffix and artifact name
      id: meta
      run: |
        ARCH=$(uname -m)
        case "$ARCH" in
          aarch64|arm64)
            ARCH_SUFFIX="aarch64"
            ;;
          x86_64|amd64)
            ARCH_SUFFIX="x86_64"
            ;;
          *)
            echo "Unsupported architecture: $ARCH" >&2
            exit 1
            ;;
        esac
        ARTIFACT="protoc-gen-grpc-web-${VERSION_NUMBER}-linux-${ARCH_SUFFIX}"
        echo "ARTIFACT=$ARTIFACT" >> "$GITHUB_ENV"
        echo "artifact=$ARTIFACT" >> "$GITHUB_OUTPUT"
        echo "Will produce artifact: $ARTIFACT"
    - name: Install Bazelisk (Bazel)
      run: |
        sudo apt-get update
        sudo apt-get install -y unzip zip
        ARCH=$(uname -m)
        case "$ARCH" in
          aarch64|arm64)
            BAZELISK_URL="https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-arm64"
            ;;
          x86_64|amd64)
            BAZELISK_URL="https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-amd64"
            ;;
          *)
            echo "Unsupported architecture for Bazelisk: $ARCH" >&2
            exit 1
            ;;
        esac
        echo "Downloading Bazelisk from $BAZELISK_URL"
        sudo curl -L -o /usr/local/bin/bazelisk "$BAZELISK_URL"
        sudo chmod +x /usr/local/bin/bazelisk
        # Also provide `bazel` symlink for tools that expect it
        sudo ln -sf /usr/local/bin/bazelisk /usr/local/bin/bazel
        bazelisk version
    - name: Build protoc-gen-grpc-web with Bazel (older glibc baseline)
      run: |
        # Partially static link libstdc++/libgcc to reduce GLIBCXX constraints
        bazelisk build \
          --linkopt=-static-libstdc++ \
          --linkopt=-static-libgcc \
          //javascript/net/grpc/web/generator:protoc-gen-grpc-web
    - name: Move artifact
      run: |
        mv bazel-bin/javascript/net/grpc/web/generator/protoc-gen-grpc-web \
          ./${ARTIFACT}
    - name: Generate sha256
      run: |
        openssl dgst -sha256 -r -out ${ARTIFACT}.sha256 \
          ${ARTIFACT}
    - name: Verify sha256
      run: sha256sum -c ${ARTIFACT}.sha256
    - name: Upload artifacts
      uses: actions/upload-artifact@v4
      with:
        name: ${{ steps.meta.outputs.artifact }}
        path: protoc-gen-grpc-web*
 

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 1 job (2 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