Make Linux Plugin workflow (grpc/grpc-web)
The Make Linux Plugin workflow from grpc/grpc-web, explained and optimized by Latchkey.
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 →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
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
- Cancel superseded runs when a branch or PR gets a newer push.
- Add a job timeout so a hung step cannot burn hours of runner time.
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:
- Dependency installs
- Network fetches
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.