Docker Bake + Github Actions + Private Repository + uv

Docker Bake + Github Actions + Private Repository + uv

How to authenticate a private Github repository in Docker Bake running in Github Actions when installing a Python package with uv

Symptom

You try to install Python dependencies in Github Actions using a private Github repository as a source. You receive an error like:

fatal: could not read Username for 'https://github.com': No such device
remote: Repository not found.
fatal: repository 'https://github.com/example/repo/' not found

Issue

The GITHUB_TOKEN secret that is available in Github Actions environments does NOT have access to other private repositories.

Here's a sample pyproject.toml that can break, where example/otherproj is an example private repository:

[project]
name = "myproj"
version = "0.1.0"
dependencies = [
    "otherproj",
]

[tool.uv.sources]
otherproj = { git = "https://github.com/example/otherproj" } # my private repo

This will work fine locally, but fail when you uv sync it in Github Actions.

Solution

You need to create a Github PAT with permissions to access the private repository and pipe it through to the uv sync command.

Here's an example of one way to do it:

  1. Create a Github PAT with repo permissions at https://github.com/settings/tokens.

gh-pat

  1. Add that token as a "repository secret" in the repo that you're running the build action in. This is under "Settings" > "Secrets and variables" > "Actions" > "New repository secret". I'll use UV_GH_TOKEN as the name below.

secret-set

  1. Update your Github Action workflow to pass the token into the docker/bake-action step. I left the permissions section in the example below so that other steps can use the limited token.

.github/workflows/docker.yaml:

name: Build Docker Images

on:
  push:

jobs:
  build-and-push:
    runs-on: ubuntu-latest

    permissions:
      id-token: write
      contents: read

    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-buildx-action@v3

      - name: Build and push
        uses: docker/bake-action@v6
        env:
          UV_GH_TOKEN: ${{ secrets.UV_GH_TOKEN }}
        with:
          files: docker-bake.json
          set: |
            *.platform=linux/amd64
            *.secrets+=id=github_token,env=UV_GH_TOKEN
  1. Set the token in the Docker image's .netrc file during uv sync, deleting it after to avoid leaking it in the image. uv will respect this during installation.
RUN --mount=type=secret,id=github_token \
    echo "machine github.com login x-access-token password $(cat /run/secrets/github_token)" > ~/.netrc \
    uv sync \
    && rm ~/.netrc

Better Option?

Let me know if you find a better way to do this!