Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: release automation #4083

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
72 changes: 20 additions & 52 deletions .github/workflows/build.yml
Expand Up @@ -8,13 +8,9 @@ on:
push:
branches:
- 'main'
- 'release/*'
tags:
- 'v*'
pull_request:

env:
DOCKERHUB_SLUG: distribution/distribution
GHCR_SLUG: ghcr.io/${{ github.repository }}

permissions:
Expand All @@ -35,10 +31,10 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't think this is needed for this PR. I think we should use dependabot to update actions.

-
name: Set up Go
uses: actions/setup-go@v3
uses: actions/setup-go@v4
with:
go-version: ${{ matrix.go }}
-
Expand All @@ -53,70 +49,53 @@ jobs:

build:
permissions:
contents: write # to create GitHub release (softprops/action-gh-release)
packages: write # so we can push the image to GHCR
id-token: write # to write to GHCR
packages: write # to write to GHCR

runs-on: ubuntu-latest
needs:
- test
steps:
-
name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
-
name: Docker meta
id: meta
uses: docker/metadata-action@v4
uses: docker/metadata-action@v5
with:
images: |
${{ env.DOCKERHUB_SLUG }}
${{ env.GHCR_SLUG }}
### versioning strategy
### push semver tag v3.2.1 on main (default branch)
# distribution/distribution:3.2.1
# distribution/distribution:3.2
# distribution/distribution:3
# distribution/distribution:latest
### push semver prelease tag v3.0.0-beta.1 on main (default branch)
# distribution/distribution:3.0.0-beta.1
### push on main
# distribution/distribution:edge
### push on PRs and main
# ghcr.io/distribution/distribution:pr<number>
# ghcr.io/distribution/distribution:sha<sha>
# ghcr.io/distribution/distribution:main
# ghcr.io/distribution/distribution:edge
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=ref,event=pr
type=ref,event=branch
type=sha
type=edge
labels: |
org.opencontainers.image.title=Distribution
org.opencontainers.image.description=The toolkit to pack, ship, store, and distribute container content
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Login to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

-
name: Log in to GitHub Container registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v2
uses: docker/setup-buildx-action@v3
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

-
name: Build artifacts
uses: docker/bake-action@v2
uses: docker/bake-action@v4
with:
targets: artifact-all
provenance: false
-
name: Move artifacts
run: |
Expand All @@ -130,21 +109,10 @@ jobs:
if-no-files-found: error
-
name: Build image
uses: docker/bake-action@v2
uses: docker/bake-action@v4
with:
files: |
./docker-bake.hcl
${{ steps.meta.outputs.bake-file }}
targets: image-all
push: ${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') }}
-
name: GitHub Release
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
draft: true
files: |
bin/*.tar.gz
bin/*.sha256
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
push: true
51 changes: 51 additions & 0 deletions .github/workflows/release-validate.yml
@@ -0,0 +1,51 @@
name: release-validation
Copy link
Contributor

@crazy-max crazy-max Dec 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why we would need this workflow? Do we not trust GH events?


on:
pull_request_target:
types:
- opened
- edited
- synchronize

permissions:
contents: read # to fetch code (actions/checkout)
pull-requests: read # to fetch PR title (amannn/action-semantic-pull-request)

jobs:
validate-pr-title:
name: Validate PR title
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
check-release: # make sure commits are valid for a target branch
name: Check valid release version
runs-on: ubuntu-latest
permissions:
contents: write # needed since semantic release checks this permission even in dry-run mode
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.base.ref }}
- name: setup node
uses: actions/setup-node@v3
with:
node-version: 20
- name: install semantic release
run: npm install -g semantic-release@22.0.5 conventional-changelog-conventionalcommits@7.0.2
- name: temporarily merge PR branch
run: |
git config --global user.name github-actions
git config --global user.email github-actions@github.com
git merge --no-ff origin/${{ github.event.pull_request.head.ref }} --message "${{ github.event.pull_request.title }}"
- name: semantic release dry run
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
unset GITHUB_EVENT_PATH
unset GITHUB_ACTIONS
unset GITHUB_EVENT_NAME
semantic-release --dry-run --ci false --semantic-version 22.0.5
128 changes: 128 additions & 0 deletions .github/workflows/release.yml
@@ -0,0 +1,128 @@
name: release
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why a new workflow? This adds so much fragmentation. Build workflow already handles properly pr,push,tags events and sets the right tags based on these events through the metadata action: https://github.com/docker/metadata-action#typesemver

See for example latest beta tags: https://github.com/distribution/distribution/actions/runs/7264017733/job/19790726671#step:3:54


on:
workflow_dispatch: # allow a release to be triggered manually

env:
GHCR_SLUG: ghcr.io/${{ github.repository }}
DOCKERHUB_SLUG: distribution/distribution

permissions:
contents: read # to fetch code (actions/checkout)

jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
go:
- 1.20.7
- 1.21.0
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: ${{ matrix.go }}
- name: Test
run: |
make coverage
- name: Codecov
uses: codecov/codecov-action@v3
with:
directory: ./

build:
permissions:
contents: write # to create GitHub release (cycjimmy/semantic-release-action)
id-token: write # to write to GHCR
packages: write # to write to GHCR

runs-on: ubuntu-latest
needs:
- test
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Semantic Release
uses: cycjimmy/semantic-release-action@v4
id: semantic_release
with:
dry_run: true
semantic_version: 22.0.5
extra_plugins: |
conventional-changelog-conventionalcommits
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Docker meta
id: meta
if: ${{ steps.semantic_release.outputs.new_release_published }}
uses: docker/metadata-action@v5
with:
images: |
name=${{ env.DOCKERHUB_SLUG }},enable=${{ github.repository_owner == 'distribution' }}
name=${{ env.GHCR_SLUG }}
### versioning strategy
### push semver tag v3.2.1 on main (default branch)
# distribution/distribution:3.2.1
# distribution/distribution:3.2
# distribution/distribution:3
# ghcr.io/distribution/distribution:3.2.1
# ghcr.io/distribution/distribution:3.2
# ghcr.io/distribution/distribution:3
tags: |
type=semver,pattern={{version}},value=${{ steps.semantic_release.outputs.new_release_version }}
type=raw,value=${{ steps.semantic_release.outputs.new_release_major_version }}.${{ steps.semantic_release.outputs.new_release_minor_version }}
type=raw,value=${{ steps.semantic_release.outputs.new_release_major_version }}
labels: |
org.opencontainers.image.title=Distribution
org.opencontainers.image.description=The toolkit to pack, ship, store, and deliver container content
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
if: ${{ github.repository_owner == 'distribution' }}
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build artifacts
uses: docker/bake-action@v4
with:
set: artifact.args.RELEASE_VERSION=v${{ steps.semantic_release.outputs.new_release_version }}
targets: artifact-all
provenance: false
- name: Move artifacts
run: |
mv ./bin/**/* ./bin/
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: registry
path: ./bin/*
if-no-files-found: error
- name: Build image
uses: docker/bake-action@v4
with:
files: |
./docker-bake.hcl
${{ steps.meta.outputs.bake-file }}
targets: image-all
push: true
- name: Semantic Release
uses: cycjimmy/semantic-release-action@v4
with:
semantic_version: 22.0.5
extra_plugins: |
conventional-changelog-conventionalcommits
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
46 changes: 46 additions & 0 deletions .github/workflows/scheduled-release.yml
@@ -0,0 +1,46 @@
name: scheduled release
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This workflow is not needed imo, The metadata-action in build workflow already sets the right tags based on semver: https://github.com/docker/metadata-action#typesemver


on:
# schedule: #TODO: enable schedule once we've gone through the release process and are confortable with it
# - cron: '0 0 1 * *' # run release monthly
workflow_dispatch: # allow a release to be triggered manually

permissions:
actions: write # needed to trigger other workflows

jobs:
build-branch-matrix:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # No shallow clone, we need all history
- name: generate matrix
id: generate-matrix
shell: bash
run: |
branches=('main' 'alpha' 'beta' 'rc')
regex='^([0-9])?(\.([0-9]|x))?\.x$' # matches branches like 1.x or 2.0.x

for branch in $(git for-each-ref --format='%(refname)' refs/remotes/origin/ | cut -d/ -f4-); do
if [[ $branch =~ $regex ]]; then
branches+=("$branch")
fi
done

echo "matrix=$(printf '%s\n' "${branches[@]}" | jq -R . | jq -s . | jq '{branch: .}' | jq -c .)" >> $GITHUB_OUTPUT
outputs:
matrix: ${{ steps.generate-matrix.outputs.matrix }}
run-release:
needs: build-branch-matrix
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.build-branch-matrix.outputs.matrix) }}
steps:
- name: Invoke workflow without inputs
uses: benc-uk/workflow-dispatch@v1
with:
workflow: release
ref: ${{ matrix.branch }}
28 changes: 28 additions & 0 deletions .releaserc
@@ -0,0 +1,28 @@
{
"branches": [
"main",
"+([0-9])?(.{+([0-9]),x}).x",
"next",
{ name: "alpha", prerelease: true },
{ name: "beta", prerelease: true },
{ name: "rc", prerelease: true },
],
"plugins": [
[
"@semantic-release/commit-analyzer",
{
"preset": "conventionalcommits"
}
],
"@semantic-release/release-notes-generator",
[
"@semantic-release/github",
{
"assets": [
{ "path": "bin/*.tar.gz" },
{ "path": "bin/*.sha256" }
]
}
]
]
}