Skip to content
Latchkey

Make Windows Plugin workflow (grpc/grpc-web)

The Make Windows 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-windows.ymlLicense Apache-2.0View source

What it does

This is the Make Windows 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 Windows Plugin

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

jobs:
  build:
    strategy:
      fail-fast: false
      matrix:
        os: [windows-2025, windows-11-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
          # Minimal sanitization: replace slashes with dashes to keep filenames valid
          VERSION="${VERSION//\//-}"
          echo "VERSION_NUMBER=$VERSION" >> "$GITHUB_ENV"
          echo "Computed VERSION_NUMBER=$VERSION"
        shell: bash
      - name: Compute ARCH suffix and artifact name
        id: meta
        shell: powershell
        run: |
          $arch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture
          switch ($arch) {
            'Arm64' { $archSuffix = 'aarch64' }
            'X64'   { $archSuffix = 'x86_64' }
            default { Write-Error "Unsupported architecture: $arch"; exit 1 }
          }
          $artifact = "protoc-gen-grpc-web-$($env:VERSION_NUMBER)-windows-$archSuffix.exe"
          "ARTIFACT=$artifact" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
          "artifact=$artifact" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
          Write-Host "Will produce artifact: $artifact"
      - name: Install Bazelisk (Bazel)
        shell: powershell
        run: |
          $arch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture
          switch ($arch) {
            'Arm64' { $suffix = 'arm64' }
            'X64'   { $suffix = 'amd64' }
            default { Write-Error "Unsupported architecture: $arch"; exit 1 }
          }
          $url = "https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-windows-$suffix.exe"
          $destDir = "$env:RUNNER_TEMP"
          $dest = Join-Path $destDir 'bazelisk.exe'
          Write-Host "Downloading Bazelisk from $url to $dest"
          Invoke-WebRequest -UseBasicParsing -Uri $url -OutFile $dest
          # Add to PATH for subsequent steps
          $destDir | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
      - name: Print Bazelisk version
        shell: powershell
        run: bazelisk version
      - name: Build protoc-gen-grpc-web with Bazel
        run: bazelisk --noworkspace_rc --bazelrc=.bazelrc.windows build //javascript/net/grpc/web/generator:protoc-gen-grpc-web
        shell: powershell
      - name: Move artifact
        run: |
          mv bazel-bin/javascript/net/grpc/web/generator/protoc-gen-grpc-web.exe "./${ARTIFACT}"
        shell: bash
      - name: Generate sha256
        run: |
          openssl dgst -sha256 -r -out "${ARTIFACT}.sha256" "${ARTIFACT}"
        shell: bash
      - name: Verify sha256
        shell: powershell
        run: |
          $shaFile = "${env:ARTIFACT}.sha256"
          if (-not (Test-Path $shaFile)) { Write-Error "SHA256 file not found: $shaFile"; exit 1 }
          $line = Get-Content -Raw $shaFile
          if (-not $line) { Write-Error "Empty sha256 file: $shaFile"; exit 1 }
          $expected = ($line -split '\s+')[0].ToLower()
          $actual = (Get-FileHash "${env:ARTIFACT}" -Algorithm SHA256).Hash.ToLower()
          if ($actual -ne $expected) {
            Write-Error "SHA256 mismatch. Expected $expected, got $actual"
            exit 1
          } else {
            Write-Host "SHA256 verified: $actual"
          }
      - 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 Windows Plugin
 
on:
  push:
    paths:
      - .github/workflows/make-plugin-windows.yml
  pull_request:
    paths:
      - .github/workflows/make-plugin-windows.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: [windows-2025, windows-11-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
          # Minimal sanitization: replace slashes with dashes to keep filenames valid
          VERSION="${VERSION//\//-}"
          echo "VERSION_NUMBER=$VERSION" >> "$GITHUB_ENV"
          echo "Computed VERSION_NUMBER=$VERSION"
        shell: bash
      - name: Compute ARCH suffix and artifact name
        id: meta
        shell: powershell
        run: |
          $arch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture
          switch ($arch) {
            'Arm64' { $archSuffix = 'aarch64' }
            'X64'   { $archSuffix = 'x86_64' }
            default { Write-Error "Unsupported architecture: $arch"; exit 1 }
          }
          $artifact = "protoc-gen-grpc-web-$($env:VERSION_NUMBER)-windows-$archSuffix.exe"
          "ARTIFACT=$artifact" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
          "artifact=$artifact" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
          Write-Host "Will produce artifact: $artifact"
      - name: Install Bazelisk (Bazel)
        shell: powershell
        run: |
          $arch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture
          switch ($arch) {
            'Arm64' { $suffix = 'arm64' }
            'X64'   { $suffix = 'amd64' }
            default { Write-Error "Unsupported architecture: $arch"; exit 1 }
          }
          $url = "https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-windows-$suffix.exe"
          $destDir = "$env:RUNNER_TEMP"
          $dest = Join-Path $destDir 'bazelisk.exe'
          Write-Host "Downloading Bazelisk from $url to $dest"
          Invoke-WebRequest -UseBasicParsing -Uri $url -OutFile $dest
          # Add to PATH for subsequent steps
          $destDir | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
      - name: Print Bazelisk version
        shell: powershell
        run: bazelisk version
      - name: Build protoc-gen-grpc-web with Bazel
        run: bazelisk --noworkspace_rc --bazelrc=.bazelrc.windows build //javascript/net/grpc/web/generator:protoc-gen-grpc-web
        shell: powershell
      - name: Move artifact
        run: |
          mv bazel-bin/javascript/net/grpc/web/generator/protoc-gen-grpc-web.exe "./${ARTIFACT}"
        shell: bash
      - name: Generate sha256
        run: |
          openssl dgst -sha256 -r -out "${ARTIFACT}.sha256" "${ARTIFACT}"
        shell: bash
      - name: Verify sha256
        shell: powershell
        run: |
          $shaFile = "${env:ARTIFACT}.sha256"
          if (-not (Test-Path $shaFile)) { Write-Error "SHA256 file not found: $shaFile"; exit 1 }
          $line = Get-Content -Raw $shaFile
          if (-not $line) { Write-Error "Empty sha256 file: $shaFile"; exit 1 }
          $expected = ($line -split '\s+')[0].ToLower()
          $actual = (Get-FileHash "${env:ARTIFACT}" -Algorithm SHA256).Hash.ToLower()
          if ($actual -ne $expected) {
            Write-Error "SHA256 mismatch. Expected $expected, got $actual"
            exit 1
          } else {
            Write-Host "SHA256 verified: $actual"
          }
      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: ${{ steps.meta.outputs.artifact }}
          path: protoc-gen-grpc-web*
 

What changed

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