About GitHub Packages with GitHub Actions
GitHub Actions help you automate your software development workflows in the same place you store code and collaborate on pull requests and issues. You can write individual tasks, called actions, and combine them to create a custom workflow. With GitHub Actions you can build end-to-end continuous integration (CI) and continuous deployment (CD) capabilities directly in your repository. For more information, see "About GitHub Actions."
You can extend the CI and CD capabilities of your repository by publishing or installing packages as part of your workflow.
Authenticating to the Container registry
Note: The Container registry is currently in public beta and subject to change. During the beta, storage and bandwidth are free. To use the Container registry, you must enable the feature preview. For more information, see "Introduction to GitHub Packages" and "Enabling improved container support with the Container registry."
PATs can grant broad access to your account. You should select only the necessary read:packages
, write:packages
, or delete:packages
scope when creating a PAT to authenticate to the Container registry.
To authenticate to the Container registry within a GitHub Actions workflow, use the GITHUB_TOKEN
for the best security and experience.
For guidance on updating your workflows that authenticate to ghcr.io
with a personal access token, see "Upgrading a workflow that accesses ghcr.io
."
The Container registry now supports GITHUB_TOKEN
for easy and secure authentication in your workflows. If your workflow is using a personal access token (PAT) to authenticate to ghcr.io
, then we highly recommend you update your workflow to use GITHUB_TOKEN
.
For more information about GITHUB_TOKEN
, see "Authentication in a workflow."
If you'd like to use the Container registry in actions during the beta, follow our security best practices for PAT use at "Security hardening for GitHub Actions."
For an authentication example, see "Authenticating with the Container registry."
Authenticating to package registries on GitHub
If you want your workflow to authenticate to GitHub Packages to access a package registry other than the Container registry on GitHub, then we recommend using the GITHUB_TOKEN
that GitHub automatically creates for your repository when you enable GitHub Actions instead of a personal access token for authentication. You should set the permissions for this access token in the workflow file to grant read access for the contents
scope and write access for the packages
scope. For forks, the GITHUB_TOKEN
is granted read access for the parent repository. For more information, see "Authenticating with the GITHUB_TOKEN."
You can reference the GITHUB_TOKEN
in your workflow file using the {{secrets.GITHUB_TOKEN}}
context. For more information, see "Authenticating with the GITHUB_TOKEN."
About permissions and package access for repository-owned packages
Note: Repository-owned packages include RubyGems, npm, Apache Maven, NuGet, Gradle, and Docker packages that use the package namespace docker.pkg.github.com
.
When you enable GitHub Actions, GitHub installs a GitHub App on your repository. The GITHUB_TOKEN
secret is a GitHub App installation access token. You can use the installation access token to authenticate on behalf of the GitHub App installed on your repository. The token's permissions are limited to the repository that contains your workflow. For more information, see "Permissions for the GITHUB_TOKEN."
GitHub Packages allows you to push and pull packages through the GITHUB_TOKEN
available to a GitHub Actions workflow.
About permissions and package access for Container registry
The Container registry (ghcr.io
) allows users to create and administer containers as free-standing resources at the organization level. Containers can be owned by an organization or personal user account and you can customize access to each of your containers separately from repository permissions.
All workflows accessing the Container registry should use the GITHUB_TOKEN
instead of a personal access token. For more information about security best practices, see "Security hardening for GitHub Actions."
Default permissions and access settings for containers modified through workflows
When you create, install, modify, or delete a container through a workflow, there are some default permission and access settings used to ensure admins have access to the workflow. You can adjust these access settings as well.
For example, by default if a workflow creates a container using the GITHUB_TOKEN
, then:
- The container inherits the visibility and permissions model of the repository where the workflow is run.
- Repository admins where the workflow is run become the admins of the container once the container is created.
These are more examples of how default permissions work for workflows that manage packages.
GitHub Actions workflow task | Default permissions and access |
---|---|
Download an existing container | - If the container is public, any workflow running in any repository can download the container. - If the container is internal, then all workflows running in any repository owned by the Enterprise account can download the container. For enterprise-owned organizations, you can read any repository in the enterprise - If the container is private, only workflows running in repositories that are given read permission on that container can download the container. |
Upload a new version to an existing container | - If the container is private, internal, or public, only workflows running in repositories that are given write permission on that container can upload new versions to the container. |
Delete a container or versions of a container | - If the container is private, internal, or public, only workflows running in repositories that are given delete permission can delete existing versions of the container. |
You can also adjust access to containers in a more granular way or adjust some of the default permissions behavior. For more information, see "Configuring a package’s access control and visibility."
Publishing a package using an action
You can use GitHub Actions to automatically publish packages as part of your continuous integration (CI) flow. This approach to continuous deployment (CD) allows you to automate the creation of new package versions, if the code meets your quality standards. For example, you could create a workflow that runs CI tests every time a developer pushes code to a particular branch. If the tests pass, the workflow can publish a new package version to GitHub Packages.
Configuration steps vary by package client. For general information about configuring a workflow for GitHub Actions, see "Configuring a workflow."
The following example demonstrates how you can use GitHub Actions to build and test your app, and then automatically create a Docker image and publish it to GitHub Packages:
-
Create a new workflow file in your repository (such as
.github/workflows/deploy-image.yml
), and add the following YAML:YAML name: Create and publish a package on: push: branches: ['release'] jobs: run-npm-build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: npm install and build webpack run: | npm install npm run build - uses: actions/upload-artifact@main with: name: webpack artifacts path: public/ run-npm-test: runs-on: ubuntu-latest needs: run-npm-build strategy: matrix: os: [ubuntu-latest] node-version: [12.x, 14.x] steps: - uses: actions/checkout@v2 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} - uses: actions/download-artifact@main with: name: webpack artifacts path: public - name: npm install, and test run: | npm install npm test env: CI: true build-and-push-image: runs-on: ubuntu-latest needs: run-npm-test permissions: contents: read packages: write steps: - name: Checkout uses: actions/checkout@v2 - name: Log in to GitHub Docker Registry uses: docker/login-action@v1 with: registry: docker.pkg.github.com username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build container image uses: docker/build-push-action@v2 with: push: true tags: | docker.pkg.github.com/${{ github.repository }}/octo-image:${{ github.sha }} docker.pkg.github.com/${{ github.repository }}/octo-image:${{ github.ref }}
The relevant settings are explained in the following table:
on: push: branches: ['release']
Configures the Create and publish a package
workflow to run every time a change is pushed to the branch calledrelease
.run-npm-build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: npm install and build webpack run: | npm install npm run build - uses: actions/upload-artifact@main with: name: webpack artifacts path: public/
This job installs NPM and uses it to build the app. run-npm-test: runs-on: ubuntu-latest needs: run-npm-build strategy: matrix: os: [ubuntu-latest] node-version: [14.x] steps: - uses: actions/checkout@v2 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} - uses: actions/download-artifact@main with: name: webpack artifacts path: public - name: npm install, and test run: | npm install npm test env: CI: true
This job uses npm test
to test the code. Theneeds: run-npm-build
command makes this job dependent on therun-npm-build
job.build-and-push-image: runs-on: ubuntu-latest needs: run-npm-test
This job publishes the package. The needs: run-npm-test
command makes this job dependent on therun-npm-test
job.permissions: contents: read packages: write
Sets the permissions granted to the GITHUB_TOKEN
for the actions in this job.- name: Log in to GitHub Docker Registry uses: docker/login-action@v1 with: registry: docker.pkg.github.com username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }}
Creates a new step called Log in to GitHub Docker Registry
, which logs in to the registry using the account and password that will publish the packages. Once published, the packages are owned by the account defined here.- name: Build container image
Creates a new step called Build container image
. This step runs as part of thebuild-and-push-image
job.uses: docker/build-push-action@v2
Uses the Docker build-push-action
action to build the image, based on your repository'sDockerfile
. If the build succeeds, it pushes the image to GitHub Packages.with:
Sends the required parameters to the build-push-action
action. This are defined in the subsequent lines.push: true
Push this image to the registry if it is built successfully. tags: | docker.pkg.github.com/${{ github.repository }}/octo-image:${{ github.sha }} docker.pkg.github.com/${{ github.repository }}/octo-image:${{ github.ref }}
Tags the published package with the git ref (for example, the name of the branch used to create the package) as well as the commit SHA. - This new workflow will run automatically every time you push a change to a branch named
release
in the repository. You can view the progress in the Actions tab. - A few minutes after the workflow has completed, the new package will visible in your repository. To find your available packages, see "Viewing a repository's packages."
Installing a package using an action
You can install packages as part of your CI flow using GitHub Actions. For example, you could configure a workflow so that anytime a developer pushes code to a pull request, the workflow resolves dependencies by downloading and installing packages hosted by GitHub Packages. Then, the workflow can run CI tests that require the dependencies.
Installing packages hosted by GitHub Packages through GitHub Actions requires minimal configuration or additional authentication when you use the
GITHUB_TOKEN
. Data transfer is also free when an action installs a package. For more information, see "About billing for GitHub Packages."Configuration steps vary by package client. For general information about configuring a workflow for GitHub Actions, see "Configuring a workflow."
Upgrading a workflow that accesses
ghcr.io
The Container registry now supports
GITHUB_TOKEN
for easy and secure authentication in your workflows. If your workflow is using a personal access token (PAT) to authenticate toghcr.io
, then we highly recommend you update your workflow to useGITHUB_TOKEN
.For more information about
GITHUB_TOKEN
, see "Authentication in a workflow."Using the
GITHUB_TOKEN
instead of a PAT, which includes therepo
scope, increases the security of your repository as you don't need to use a long-lived PAT that offers unnecessary access to the repository where your workflow is run. For more information about security best practices, see "Security hardening for GitHub Actions."-
Navigate to your package landing page.
-
In the left sidebar, click Actions access.
-
To ensure your container package has access to your workflow, you must add the repository where the workflow is stored to your container. Click Add repository and search for the repository you want to add.
Note: Adding a repository to your container through the Actions access menu option is different than connecting your container to a repository. For more information, see "Ensuring workflow access to your package" and "Connecting a repository to a package."
-
Optionally, using the "role" drop-down menu, select the default access level that you'd like the repository to have to your container image.
-
Open your workflow file. On the line where you login to
ghcr.io
, replace your PAT with${{ secrets.GITHUB_TOKEN }}
.
For example, this workflow publishes a Docker container using
${{ secrets.GITHUB_TOKEN }}
to authenticate.YAML name: Demo Push on: push: # Publish `master` as Docker `latest` image. branches: - master - seed # Publish `v1.2.3` tags as releases. tags: - v* # Run tests for any PRs. pull_request: env: IMAGE_NAME: ghtoken_product_demo jobs: # Push image to GitHub Packages. # See also https://docs.docker.com/docker-hub/builds/ push: runs-on: ubuntu-latest permissions: packages: write contents: read steps: - uses: actions/checkout@v2 - name: Build image run: docker build . --file Dockerfile --tag $IMAGE_NAME --label "runnumber=${GITHUB_RUN_ID}" - name: Log into registry # This is where you will update the PAT to GITHUB_TOKEN run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin - name: Push image run: | IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME # Change all uppercase to lowercase IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') # Strip git ref prefix from version VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,') # Strip "v" prefix from tag name [[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//') # Use Docker `latest` tag convention [ "$VERSION" == "master" ] && VERSION=latest echo IMAGE_ID=$IMAGE_ID echo VERSION=$VERSION docker tag $IMAGE_NAME $IMAGE_ID:$VERSION docker push $IMAGE_ID:$VERSION
- This new workflow will run automatically every time you push a change to a branch named