Skip to content

Commit

Permalink
chore: Update release automation
Browse files Browse the repository at this point in the history
Closes: vmware#2875
Signed-off-by: Michael Gasch <mgasch@vmware.com>
  • Loading branch information
Michael Gasch committed Jun 15, 2022
1 parent 62e5b57 commit 80489cb
Show file tree
Hide file tree
Showing 2 changed files with 257 additions and 29 deletions.
104 changes: 95 additions & 9 deletions .github/workflows/govmomi-release.yaml
Expand Up @@ -15,15 +15,26 @@
name: Release

on:
push:
tags:
- "v*" # Push events to matching v*, i.e. v0.25.0, v1.15.1
workflow_dispatch:
inputs:
tag:
description: 'Create release using this non-existing semantic tag for the specified ref'
required: true
type: string
default: 'v0.99.0'
dryrun:
description: 'Verify release workflow without pushing any changes (catches most but not all errors)'
type: boolean
required: false
default: true

jobs:
release:
name: Create Release
runs-on: ubuntu-20.04
timeout-minutes: 60
outputs:
latesttag: ${{ steps.tag.outputs.islatest }}

steps:
- name: Docker Login
Expand All @@ -33,20 +44,82 @@ jobs:
uses: actions/checkout@v3
with:
fetch-depth: 0 # for CHANGELOG
ref: ${{ github.ref }} # branch provided on dispatch

- name: Validate branch and tag
run: |
# do not allow release on master branch
if [[ ${{ github.ref }} == refs/heads/master ]]; then
echo "::error:: release must be done on a release branch"
exit 1
fi
# check it starts with "v"
if [[ ${{ inputs.tag }} != v* ]]; then
echo "::error:: tag must have a \"v\" prefix"
exit 1
fi
# check it does not exist
if [[ $(git tag -l ${{ inputs.tag }} ) ]]; then
echo "::error:: tag already exists"
exit 1
fi
# set tag environment variable
echo "TAG=${{ inputs.tag }}" >> $GITHUB_ENV
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.18

- name: Update version.go
run: |
# strip semantic v
export GOVMOMI_VERSION=${TAG#"v"}
sed -i "s/ClientVersion =.*/ClientVersion = \"$GOVMOMI_VERSION\"/" internal/version/version.go
git --no-pager diff internal/version/version.go
# configure author
# https://github.community/t/github-actions-bot-email-address/17204/6
git config --local user.email 41898282+github-actions[bot]@users.noreply.github.com
git config --local user.name "GitHub Action"
# commit changes
git add internal/version/version.go
git commit -s -m "chore: Update version.go for ${TAG}"
- name: Create tag
id: tag
run: |
# create new tag
git tag -a ${TAG} -m "Release ${TAG}"
# find latest tag sorted by semver ref
LATEST=$(git tag --sort=v:refname | tail -1)
# check whether the new tag is also the latest
if [[ $LATEST == $TAG ]]; then
echo "::set-output name=islatest::true"
else
echo "::set-output name=islatest::false"
fi
- name: Push changes and tag to release branch
if: ${{ !inputs.dryrun }}
run: |
git push --atomic --follow-tags origin ${{ github.ref }}
- name: Create RELEASE CHANGELOG
env:
IMAGE: quay.io/git-chglog/git-chglog
# https://quay.io/repository/git-chglog/git-chglog from tag v0.14.2
IMAGE_SHA: 998e89dab8dd8284cfff5f8cfb9e9af41fe3fcd4671f2e86a180e453c20959e3
run: |
# generate CHANGELOG for this Github release tag only
docker run --rm -v $PWD:/workdir ${IMAGE}@sha256:${IMAGE_SHA} -o RELEASE_CHANGELOG.md --sort semver --tag-filter-pattern '^v[0-9]+' $(basename "${{ github.ref }}" )
docker run --rm -v $PWD:/workdir ${IMAGE}@sha256:${IMAGE_SHA} -o RELEASE_CHANGELOG.md --sort semver --tag-filter-pattern '^v[0-9]+' ${TAG}
- name: Archive CHANGELOG
uses: actions/upload-artifact@v3
Expand All @@ -57,7 +130,18 @@ jobs:
./RELEASE_CHANGELOG.md
retention-days: 14

- name: Simulate Release without pushing Artifacts
if: ${{ inputs.dryrun }}
uses: goreleaser/goreleaser-action@v3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
version: latest
args: release --snapshot --rm-dist --release-notes RELEASE_CHANGELOG.md


- name: Create Release and build/push Artifacts
if: ${{ !inputs.dryrun }}
uses: goreleaser/goreleaser-action@v3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand All @@ -70,6 +154,8 @@ jobs:
name: Create CHANGELOG.md PR
runs-on: ubuntu-20.04
continue-on-error: true
# only update CHANGELOG for latest semver tag
if: ${{ !inputs.dryrun && needs.release.outputs.latesttag == 'true' }}

steps:
- name: Checkout
Expand All @@ -92,16 +178,16 @@ jobs:
id: cpr
uses: peter-evans/create-pull-request@v4
with:
commit-message: "Update CHANGELOG for ${{ github.ref }}"
commit-message: "Update CHANGELOG for ${{ inputs.tag }}"
delete-branch: true
title: "Update CHANGELOG for ${{ github.ref }}"
title: "Update CHANGELOG for ${{ inputs.tag }}"
signoff: true
reviewers: embano1,dougm
draft: false
body: |
Update CHANGELOG.md for new release.
### Update CHANGELOG.md for new release.
**Note:** Due to a [limitation](https://github.com/peter-evans/create-pull-request/blob/master/docs/concepts-guidelines.md#triggering-further-workflow-runs) in Github Actions please **close and immediately reopen** this PR to trigger the required workflow checks before merging.
> **Note**
> Due to a [limitation](https://github.com/peter-evans/create-pull-request/blob/master/docs/concepts-guidelines.md#triggering-further-workflow-runs) in Github Actions please **close and immediately reopen** this PR to trigger the required workflow checks before merging.
- name: Pull Request Information
run: |
Expand Down
182 changes: 162 additions & 20 deletions RELEASE.md
@@ -1,22 +1,43 @@
# How to create a new `govmomi` Release on Github
# How to create a `govmomi` Release on Github

On every new tag matching `v*` pushed to the repository a Github Action Release
Workflow is executed.
> **Note**
>
> The steps outlined in this document can only be performed by maintainers or
> administrators of this project.
The release automation is based on Github
[Actions](https://github.com/features/actions) and has been improved over time
to simplify the experience for creating `govmomi` releases.

The Github Actions release [workflow](.github/workflows/govmomi-release.yaml)
uses [`goreleaser`](http://goreleaser.com/) ([configuration
file](.goreleaser.yml)) and automatically creates/pushes:
uses [`goreleaser`](http://goreleaser.com/) and automatically creates/pushes:

- Release artifacts for `govc` and `vcsim` to the
[release](https://github.com/vmware/govmomi/releases) page, including
`LICENSE.txt`, `README` and `CHANGELOG`
- Docker images for `vmware/govc` and `vmware/vcsim` to Docker Hub
- Source code

⚠️ **Note:** These steps can only be performed by maintainers or administrators
of this project.
Starting with release tag `v0.29.0`, releases are not tagged on the `master`
branch anymore but a dedicated release branch, for example `release-0.29`. This
process has already been followed for patch releases and back-ports.

> **Warning**
>
> If you create a release after the `v0.29.0` tag, start
> [here](#creating-a-release-after-v0290). To create a release with an older
> tag, e.g. cherrypick or back-port, continue
> [here](#creating-a-release-before-v0290).
## Creating a release after Version `v0.29.0`

The release process from `v0.29.0` has been further simplified and is done
through the Github UI. The only pre-requirement is creating a release branch,
which can be done through the Github UI or `git` CLI.

## Verify `master` branch is up to date with the remote
This guide describes the CLI process.

### Verify `master` branch is up to date with the remote

```console
git checkout master
Expand All @@ -27,14 +48,32 @@ git diff master origin/master
git pull origin/master
```

⚠️ **Note:** These steps assume `origin` to point to the remote
`https://github.com/vmware/govmomi`, respectively
`git@github.com:vmware/govmomi`.
> **Warning**
>
> These steps assume `origin` to point to the remote
> `https://github.com/vmware/govmomi`, respectively
> `git@github.com:vmware/govmomi`.
## Verify `make docs` and `CONTRIBUTORS` are up to date
### Create a release branch

⚠️ Run the following commands and commit (PR) any changes before proceeding with
the release.
For new releases, create a release branch from the most recent commit in
`master`, e.g. `release-0.30`.

```console
export RELEASE_BRANCH=release-0.30
git checkout -b ${RELEASE_BRANCH}
```

For maintenance/patch releases on **existing** release branches **after** tag
`v0.29.0` simply checkout the existing release branch and add commits to the
existing release branch.

### Verify `make docs` and `CONTRIBUTORS` are up to date

> **Warning**
>
> Run the following commands and commit any changes to the release branch before
> proceeding with the release.
```console
make doc
Expand All @@ -44,33 +83,136 @@ if [ -z "$(git status --porcelain)" ]; then
else
echo "working directory dirty: please commit changes"
fi

# perform git add && git commit ... in case there were changes
```

### Push the release branch

> **Warning**
>
> Do not create a tag as this will be done by the release automation.
The final step is pushing the new/updated release branch.

```console
git push origin ${RELEASE_BRANCH}
```

### Create a release in the Github UI

Open the `govmomi` Github [repository](https://github.com/vmware/govmomi) and
navigate to `Actions -> Workflows -> Release`.

Click `Run Workflow` which opens a dropdown list.

Select the new/updated branch, e.g. `release-0.30`, i.e. **not** the `master`
branch.

Specify a semantic `tag` to associate with the release, e.g. `v0.30.0`.

> **Warning**
>
> This tag **must not** exist or the release will fail during the validation
> phase.
By default, a dry-run is performed to rule out most (but not all) errors during
a release. If you do not want to perform a dry-run, e.g. to finally create a
release, deselect the `Verify release workflow ...` checkbox.

Click `Run Workflow` to kick off the workflow.

After successful completion and if the newly created `tag` is the **latest**
(semantic version sorted) tag in the repository, a PR is automatically opened
against the `master` branch to update the `CHANGELOG`. Please review and merge
accordingly.

## Creating a release before Version `v0.29.0`

The release process before `v0.29.0` differs since it's based on manually
creating and pushing tags. Here, on every new tag matching `v*` pushed to the
repository a Github Action Release Workflow is executed.

### Verify `master` branch is up to date with the remote

```console
git checkout master
git fetch -avp
git diff master origin/master

# if your local and remote branches diverge run
git pull origin/master
```

> **Warning**
>
> These steps assume `origin` to point to the remote
> `https://github.com/vmware/govmomi`, respectively
> `git@github.com:vmware/govmomi`.
### Create a release branch

Pick a reference (commit, branch or tag) **before** the `v0.29.0` tag and create
a release branch from there.

The following example creates a cherrypick release (`v0.28.1`) based on the
`v0.28.0` tag.

```console
export RELEASE_BRANCH=release-0.28
git checkout -b ${RELEASE_BRANCH} v0.28.0
```

Optionally, incorporate (cherry-pick) commits into the branch.

> **Warning**
>
> Make sure that these commits/ranges do not contain commits after the `v0.29.0`
> tag which include release automation changes, i.e. files in `.github/workflows/`!
### Verify `make docs` and `CONTRIBUTORS` are up to date

> **Warning**
>
> Run the following commands and commit any changes to the release branch before
> proceeding with the release.
```console
make doc
./scripts/contributors.sh
if [ -z "$(git status --porcelain)" ]; then
echo "working directory clean: proceed with release"
else
echo "working directory dirty: please commit changes"
fi

# perform git add && git commit ... in case there were changes
```

## Set `RELEASE_VERSION` variable
### Set `RELEASE_VERSION` variable

This variable is used and referenced in the subsequent commands. Set it to the
**upcoming** release version, adhering to the [semantic
versioning](https://semver.org/) scheme:

```console
export RELEASE_VERSION=v0.27.0
export RELEASE_VERSION=v0.28.1
```

## Create the Git Tag
### Create the Git Tag

```console
git tag -a ${RELEASE_VERSION} -m "Release ${RELEASE_VERSION}"
```

## Push the new Tag
### Push the new Tag

```console
# Will trigger Github Actions Release Workflow
git push origin refs/tags/${RELEASE_VERSION}
git push --atomic origin ${RELEASE_BRANCH} refs/tags/${RELEASE_VERSION}
```

## Verify Github Action Release Workflow
### Verify Github Action Release Workflow

After pushing a new release tag, the status of the workflow can be inspected
[here](https://github.com/vmware/govmomi/actions/workflows/govmomi-release.yaml).
Expand Down

0 comments on commit 80489cb

Please sign in to comment.