Skip to content
Latchkey

CI/CD for a CMake + vcpkg Project with GitHub Actions

Resolve deps with vcpkg manifest mode, build with CMake, and cache binaries.

vcpkg in manifest mode reads vcpkg.json and installs dependencies as part of the CMake configure step via its toolchain file. This recipe wires the toolchain, enables the binary cache, builds, and tests.

What the pipeline does

  • check out the project and the vcpkg submodule
  • enable the vcpkg binary cache to GitHub Actions cache
  • configure with the vcpkg CMake toolchain
  • build with CMake
  • run tests with CTest

The workflow

VCPKG_BINARY_SOURCES points the binary cache at the GitHub Actions cache via the NuGet-compatible provider, so prebuilt ports are reused. The toolchain file triggers manifest install during configure.

.github/workflows/ci.yml
name: CI
on:
  push:
    branches: [main]
  pull_request:
env:
  VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: true
      - uses: actions/github-script@v7
        with:
          script: |
            core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
            core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
      - run: ./vcpkg/bootstrap-vcpkg.sh
      - run: cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release
      - run: cmake --build build -j
      - run: ctest --test-dir build --output-on-failure

Caching and speed

The vcpkg binary cache (x-gha provider) stores compiled ports in the GitHub Actions cache, so dependencies build from source only once. Cold builds of large ports are slow, so cheaper managed runners such as Latchkey (around 69% cheaper than GitHub-hosted) help on the first build, and auto-retry covers a flaky port download.

Deploying

Package the built binary or library as a release artifact or container. For reproducibility, commit vcpkg.json plus a builtin baseline so every CI run resolves identical port versions.

Key takeaways

  • Manifest mode installs deps during CMake configure via the toolchain file.
  • The x-gha binary cache reuses compiled ports across runs.
  • Pin a vcpkg baseline so dependency versions are reproducible.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →