diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index fb94ef08f..3856e70c1 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,6 +1,10 @@ name: For each commit and PR on: push: + branches: + - "*" + tags-ignore: + - "v*" pull_request: env: CGO_ENABLED: 0 diff --git a/.github/workflows/tags.yaml b/.github/workflows/tags.yaml new file mode 100644 index 000000000..1dfd81216 --- /dev/null +++ b/.github/workflows/tags.yaml @@ -0,0 +1,55 @@ +on: + push: + tags: + - "v*" +name: Create release +env: + REGISTRY: quay.io + IMAGE_NAME: ${{ github.repository }} +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + - name: Generate Release Notes + run: | + release_notes=$(gh api repos/{owner}/{repo}/releases/generate-notes -F tag_name=${{ github.ref }} --jq .body) + echo 'RELEASE_NOTES<> $GITHUB_ENV + echo "${release_notes}" >> $GITHUB_ENV + echo 'EOF' >> $GITHUB_ENV + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + OWNER: ${{ github.repository_owner }} + REPO: ${{ github.event.repository.name }} + + - name: Docker manager metadata + id: meta + uses: docker/metadata-action@v3 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + flavor: latest=false + tags: type=ref,event=tag + + - name: Set the from image tag + run: echo "FROM_TAG=sha-${GITHUB_SHA::8}" >> $GITHUB_ENV + + - name: Copy the image using skopeo + run: skopeo copy --all --dest-creds="${DST_REG_USER}":"${DST_REG_PASS}" docker://"${SRC_IMAGE}" docker://"${DST_IMAGE}" + env: + SRC_IMAGE: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.FROM_TAG }} + DST_IMAGE: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} + DST_REG_USER: ${{ secrets.QUAY_USERNAME }} + DST_REG_PASS: ${{ secrets.QUAY_PASSWORD }} + + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: ${{ github.ref }} + body: ${{ env.RELEASE_NOTES }} + draft: false + prerelease: true diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 000000000..cf46e3a80 --- /dev/null +++ b/RELEASING.md @@ -0,0 +1,19 @@ +# Releasing + +## Process + +For version v0.x.y: + +1. Create the annotated tag + > NOTE: To use your GPG signature when pushing the tag, use `SIGN_TAG=1 ./contrib/tag-release.sh v0.x.y` instead) + - `./contrib/tag-release.sh v0.x.y` +1. Push the tag to the GitHub repository. This will automatically trigger a [Github Action](https://github.com/tinkerbell/tink/actions) to create a release. + > NOTE: `origin` should be the name of the remote pointing to `github.com/tinkerbell/tink` + - `git push origin v0.x.y` +1. Review the release on GitHub. + +### Permissions + +Releasing requires a particular set of permissions. + +- Tag push access to the GitHub repository diff --git a/contrib/tag-release.sh b/contrib/tag-release.sh new file mode 100755 index 000000000..34a51902b --- /dev/null +++ b/contrib/tag-release.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +set -o errexit -o nounset -o pipefail + +if [ -z "${1-}" ]; then + echo "Must specify new tag" + exit 1 +fi + +new_tag=${1-} +[[ $new_tag =~ ^v[0-9]*\.[0-9]*\.[0-9]*$ ]] || ( + echo "Tag must be in the form of vX.Y.Z" + exit 1 +) + +if [[ $(git symbolic-ref HEAD) != refs/heads/main ]] && [[ -z ${ALLOW_NON_MAIN:-} ]]; then + echo "Must be on main branch" >&2 + exit 1 +fi +if [[ $(git describe --dirty) != $(git describe) ]]; then + echo "Repo must be in a clean state" >&2 + exit 1 +fi + +git fetch --all + +last_tag=$(git describe --abbrev=0) +last_tag_commit=$(git rev-list -n1 "$last_tag") +last_specific_tag=$(git tag --contains="$last_tag_commit" | grep -E "^v[0-9]*\.[0-9]*\.[0-9]*$" | tail -n 1) +last_specific_tag_commit=$(git rev-list -n1 "$last_specific_tag") +if [[ $last_specific_tag_commit == $(git rev-list -n1 HEAD) ]]; then + echo "No commits since last tag" >&2 + exit 1 +fi + +if [[ -n ${SIGN_TAG-} ]]; then + git tag -s -m "${new_tag}" "${new_tag}" &>/dev/null && echo "created signed tag ${new_tag}" >&2 && exit +else + git tag -a -m "${new_tag}" "${new_tag}" &>/dev/null && echo "created annotated tag ${new_tag}" >&2 && exit +fi