Publishing with Github Actions

If you would like to publish your buildpack image to the registry without requiring a human click a button in a browser, you can automate the process using the helpers in the buildpacks/github-actions repository.

To begin, you must store your buildpack source code in GitHub and enable GitHub Actions. Then create a directory named .github/workflows in your repository, and add a file named release.yml to it. The release.yml workflow can be triggered in many ways, but it’s common to use a Release event as a trigger. To do so, add the following to your release.yml:

name: Release
on:
  release:
    types:
      - published

Next, you must configure a job to run when this workflow is triggered. Each workflow job is a set of steps. The steps you’ll need to run will depend on how your buildpack is built (for example, you may need to compile some code or download some artifacts). But every buildpack will need the following steps:

  1. Checkout the source code
  2. Authenticate with an OCI Registry
  3. Install Pack
  4. Run Pack to package the buildpack and publish the image
  5. Register the image with the Buildpack Registry

You can implement a job with these steps in your GitHub Action by adding the following code to your release.yml (note the indentation):

jobs:
  register:
    name: Package, Publish, and Register
    runs-on:
    - ubuntu-latest
    steps:
    - id: checkout
      uses: actions/checkout@v2
    - if: ${{ github.event_name != 'pull_request' || ! github.event.pull_request.head.repo.fork }}
      uses: docker/login-action@v1
      with:
        registry: docker.io
        username: ${{ secrets.DOCKER_HUB_USER }}
        password: ${{ secrets.DOCKER_HUB_PASS }}
    - id: setup-pack
      uses: buildpacks/github-actions/setup-pack@v4.1.0
    - id: package
      run: |
        #!/usr/bin/env bash
        set -euo pipefail
        BP_ID="$(cat buildpack.toml | yj -t | jq -r .buildpack.id)"
        VERSION="$(cat buildpack.toml | yj -t | jq -r .buildpack.version)"
        PACKAGE="${REPO}/$(echo "$BP_ID" | sed 's/\//_/g')"
        pack buildpack package --publish ${PACKAGE}:${VERSION}
        DIGEST="$(crane digest ${PACKAGE}:${VERSION})"
        echo "::set-output name=bp_id::$BP_ID"
        echo "::set-output name=version::$VERSION"
        echo "::set-output name=address::${PACKAGE}@${DIGEST}"
      shell: bash
      env:
        REPO: docker.io/${{ secrets.DOCKER_HUB_USER }}
    - id: register
      uses: docker://ghcr.io/buildpacks/actions/registry/request-add-entry:4.1.0
      with:
        token:   ${{ secrets.PUBLIC_REPO_TOKEN }}
        id:      ${{ steps.package.outputs.bp_id }}
        version: ${{ steps.package.outputs.version }}
        address: ${{ steps.package.outputs.address }}

Before you execute this GitHub Action, you must add three secrets to your GitHub repository:

  • DOCKER_HUB_USER - your Docker Hub username.
  • DOCKER_HUB_PASS - a Docker Hub access token.
  • PUBLIC_REPO_TOKEN - the value of a GitHub token with the repo:public_repo scope (the default GITHUB_TOKEN provided for GitHub Actions is not sufficient).

After you’ve created these secrets and pushed your release.yml file to GitHub you can trigger the workflow by creating a new Release using the GitHub Releases UI.

From GitHub.com, click on Your Repositories, then click the Packages tab and look for the image you just created. Click it and then select Package Settings. From this page, click the button to make this package public, and confirm the name of the image when promoted.

Push the release.yml changes to GitHub and trigger a new release. The workflow will create a GitHub Issue on the Buildpack Registry and your buildpack will be added to the index.

It is possible to perform these same step on any automated CI platform, but the Buildpack project only provides helpers for GitHub Actions.

You may store your buildpack image in any standard OCI registry, such as Docker Hub, Google Container Registry, or GitHub Container Registry. However, GitHub Packages are not supported as they provide a non-standard implementation of the OCI Registry specification.