vcpkg integration with the GitHub dependency graph

Michael Price

We are excited to share that vcpkg has an experimental feature to provide data to the GitHub dependency graph. We are actively developing this feature and would like to hear your feedback. Let us know if you have any thoughts about the current functionality or would like to see further improvements. If you have feedback on any of the GitHub features that a vcpkg-powered dependency graph enables, let us know that too and we’ll make sure that it reaches the right folks at GitHub.

About the GitHub dependency graph

The GitHub dependency graph stores the set of dependencies for a repository. Beyond just being able to visualize what a repository’s dependencies are, GitHub builds several useful features on top of this data, including dependency review and Dependabot alerts.

Enabling the GitHub dependency graph

Enabling the dependency graph for your repository is a requirement for vcpkg to be able to populate the dependencies for your repository. The dependency graph is enabled by default for public repositories on GitHub. If you want the dependency graph enabled for a private repository, you should follow the GitHub documentation to enable the dependency graph.

Screenshot showing the button to enable the dependency graph

If you are already using reusable actions in your GitHub Actions workflows and the dependency graph is enabled, there’s a good chance your repository’s dependency graph already has some dependencies listed. Check it out by selecting Insights for your repository and then selecting Dependency graph.

Screenshot of a sample repository's dependency graph

Techniques for populating the dependency graph

There are two ways that the dependency graph may get populated. For some package management systems that have a static list of dependencies that can be fully described in a manifest file, GitHub will automatically scan those manifests once they are pushed into your repository and will begin showing up in the dependency graph.

For package management systems that are more dynamic, the tools used to process the list of dependencies must be involved in determining the complete set of dependencies. The complete set of dependencies for C and C++ are usually highly dependent upon build configuration and target platform. For these ecosystems, GitHub has a dependency submission API that tools can use to provide the dependency information, usually as a part of a GitHub Actions workflow job.

Reporting dependencies with vcpkg

vcpkg integration with the GitHub dependency graph can be enabled by adding the value dependencygraph to the VCPKG_FEATURE_FLAGS environment variable within your GitHub Actions workflow file that runs vcpkg (either directly or indirectly via CMake). You must also modify your workflow file to set the GITHUB_TOKEN environment variable with the value ${{ secrets.GITHUB_TOKEN }} and request permission for the workflow job to write the dependency information into your repository’s metadata by including the following YAML snippet near the top of your workflow file.

permissions:
  contents: write

Once those changes have been made, and your workflow runs again, you should begin to see the dependencies in your vcpkg.json manifest listed in the Dependency graph section on GitHub.

See our documentation at GitHub integration – The GitHub dependency graph for more information.

Examples

A live example template repository is on GitHub if you want to try it out in a clean project. If you want to try it out on an existing project, see the workflow files defined below that shows the changes you need to make to enable the feature.

Both workflow examples below work with the vcpkg.json and main.cpp files listed here.

vcpkg.json

{
  "name": "your-project",
  "version-string": "0.0.1",
  "dependencies": [
    "fmt"
  ]
}

main.cpp

#define FMT_HEADER_ONLY
#include "fmt/color.h"

int main(int argc, char** argv)
{
    fmt::print(
        fg(fmt::color::light_salmon),
        "¡Hola, Mundo!\n"
    );
}


Indirectly through CMake integration

Add the following files to test the vcpkg dependency graph integration when using CMake.

CMakeLists.txt

cmake_minimum_required(VERSION 3.15)

project(your-project CXX)
find_package(fmt REQUIRED)
set(CMAKE_CXX_STANDARD 20)

add_executable(hola main.cpp)

target_link_libraries(hola
  PRIVATE
    fmt::fmt)

.github/workflows/cmake.yml

name: Example that uses CMake integration

on:
  workflow_dispatch:

###############################################################################
# Add this section to your workflow file does not already have it to enable
# the job to write the dependency metadata.
###############################################################################
permissions:
  contents: write

###############################################################################
# Add these environment variables to your workflow to enable the vcpkg
# dependency graph integration.
###############################################################################
env:
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  VCPKG_FEATURE_FLAGS: dependencygraph

jobs:
  cmake:
    runs-on: ubuntu-latest

    # These steps assume an appropriate version of vcpkg is listed as a
    # submodule in your git repo. If it is not, you must update this workflow
    # to obtain it.

    steps:
      - uses: actions/checkout@v3
        with:
          submodules: 'recursive'  

      - name: Bootstrap vcpkg
        run: ${{ github.workspace }}/vcpkg/bootstrap-vcpkg.sh

      - name: Configure with CMake
        run: |
          cmake -B build -S ${{ github.workspace }} \
          -DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake

      - name: Build with CMake
        run: cmake --build build

      - name: Hola, amigos
        run: ${{ github.workspace }}/build/hola


Directly calling vcpkg install

Add the following file to test the vcpkg dependency graph integration with workflows that call vcpkg install directly.

.github/workflows/build.yml

name: Example that directly invokes `vcpkg install`

on:
  push:
    branches: [ main ]
  workflow_dispatch:

###############################################################################
# Add this section to your workflow file does not already have it to enable
# the job to write the dependency metadata.
###############################################################################
permissions:
  contents: write

###############################################################################
# Add these environment variables to your workflow to enable the vcpkg
# dependency graph integration.
###############################################################################
env:
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  VCPKG_FEATURE_FLAGS: dependencygraph

jobs:
  build:
    runs-on: ubuntu-latest

    # These steps assume an appropriate version of vcpkg is listed as a
    # submodule in your git repo. If it is not, you must update this workflow
    # to obtain it.

    steps:
      - uses: actions/checkout@v3
        with:
          submodules: 'recursive'  

      - name: Bootstrap vcpkg
        run: ${{ github.workspace }}/vcpkg/bootstrap-vcpkg.sh

      - name: Directly invoke `vcpkg install`
        run: ${{ github.workspace }}/vcpkg/vcpkg install

      - name: Build with G++
        run: g++ -I${{ github.workspace }}/vcpkg_installed/x64-linux/include -o hola main.cpp

      - name: Hola, amigos
        run: ${{ github.workspace }}/hola

Call to action

We are gathering feedback from users to determine the improvements we need to make to consider this integration fully supported. This is the foundation for opening up really powerful, Enterprise-grade dependency management for our users, and we are excited to have you all try it out. You can find the feature and the latest bug fixes in the most recent commit to the vcpkg default branch.

As usual, if you have feedback, leave us a comment below or contact us on Twitter (@VisualC) or via email at visualcpp@microsoft.com.

2 comments

Discussion is closed. Login to edit/delete existing comments.

  • Matt Weir 0

    This sounds very good, however dependencies are complicated and can change over time or depending on build settings, or even on the presence or absence of other libraries in the build environment. For projects at my work, we mainly want to make sure we don’t build in anything new and unexpected without at least knowing about it. So we use vcpkg but have some automated earlier steps to remove all ports (each subfolder of the ports folder) that we don’t use, and also update each port folder to the version from a specific vcpkg commit, to ensure we are building against a known version (and we can review any new or updated dependencies/versions before accepting them, checking security aspects etc). If any of our dependencies added their own dependencies that we didn’t expect, the build would fail and we can know about it, review, etc. It would be great if vcpkg could support such a system directly. thanks

    • Michael PriceMicrosoft employee 0

      Hi Matt,

      Thanks for your comment. I agree that having an absolute understanding of the dependencies for your product can be very important for many projects. We don’t currently have any plans in vcpkg itself to track dependency changes between versions or build environments of projects, but what you have suggested does fit squarely in the realm of the secure supply chain features that GitHub supports. You can read more about them at https://docs.github.com/code-security/supply-chain-security. The feature described here is an important part of enabling those Github features for our vcpkg users.

      Thanks again for letting us know what’s important to you. If you’d like a more in-depth follow-up, please email us at visualcpp@microsoft.com.

Feedback usabilla icon