Skip to content

Commit

Permalink
ci: Automate patch releases and pre-releases
Browse files Browse the repository at this point in the history
This work by automatically pushing a new tag on main and release
branches after each commit. The
tag will be "devel" on main and the version from postgrest.cabal for
release branches. The release
workflow then runs as a tag pipeline, making the actual release.

Resolves PostgREST#2006
Resolves PostgREST#2997
  • Loading branch information
wolfgangwalther committed May 4, 2024
1 parent 1ca2d1f commit e20388a
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 53 deletions.
11 changes: 9 additions & 2 deletions .github/actions/artifact-from-cirrus/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,15 @@ runs:
}
archive="$(mktemp)"
artifacts="$(mktemp -d)"
curl --no-progress-meter --fail -o "${archive}" \
"https://api.cirrus-ci.com/v1/artifact/task/$(get_external_id)/${{ inputs.download }}.zip"
until curl --no-progress-meter --fail -o "${archive}" \
"https://api.cirrus-ci.com/v1/artifact/task/$(get_external_id)/${{ inputs.download }}.zip"
do
# This happens when a tag is pushed on the same commit. In this case the
# job is immediately marked as "completed" for us, so we end up here after a few
# seconds - but the actual Cirrus CI task is still running and didn't produce its artifact, yet.
echo "Artifact not found on Cirrus CI, yet. Waiting..."
sleep 30
done
unzip "${archive}" -d "${artifacts}"
echo "artifacts=${artifacts}" >> "$GITHUB_OUTPUT"
- name: Save artifact to GitHub Actions
Expand Down
3 changes: 1 addition & 2 deletions .github/scripts/arm/docker-publish.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ DOCKER_USER="$3"
DOCKER_PASS="$4"
SCRIPT_DIR="$5"
PGRST_VERSION="v$6"
IS_PRERELEASE="$7"

DOCKER_BUILD_DIR="$SCRIPT_DIR/docker-env"

Expand Down Expand Up @@ -45,6 +44,6 @@ sudo docker buildx build --build-arg PGRST_GITHUB_COMMIT=$PGRST_GITHUB_COMMIT \
# NOTE: This assumes that there already is a `postgrest:<version>` image
# for the amd64 architecture pushed to Docker Hub
sudo docker buildx imagetools create --append -t $DOCKER_REPO/postgrest:$PGRST_VERSION $DOCKER_REPO/postgrest:$PGRST_VERSION-arm
[ -z $IS_PRERELEASE ] && sudo docker buildx imagetools create --append -t $DOCKER_REPO/postgrest:latest $DOCKER_REPO/postgrest:$PGRST_VERSION-arm
[ "$PGRST_VERSION" != "devel" ] && sudo docker buildx imagetools create --append -t $DOCKER_REPO/postgrest:latest $DOCKER_REPO/postgrest:$PGRST_VERSION-arm

sudo docker logout
117 changes: 68 additions & 49 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
- main
- v[0-9]+
tags:
- devel
- v*

concurrency:
Expand Down Expand Up @@ -100,48 +101,66 @@ jobs:
if-no-files-found: error


prepare:
name: Release / Prepare
tag:
name: Release / Tag
if: |
startsWith(github.ref, 'refs/tags/v') &&
(success() || needs.arm.result == 'skipped')
startsWith(github.ref, 'refs/heads/') &&
needs.docs.result == 'success' &&
needs.test.result == 'success' &&
needs.build.result == 'success' &&
(needs.arm.result == 'skipped' || success())
permissions:
contents: write
runs-on: ubuntu-22.04
needs:
- docs
- test
- build
- arm
outputs:
version: ${{ steps.Identify-Version.outputs.version }}
isprerelease: ${{ steps.Identify-Version.outputs.isprerelease }}
steps:
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
- id: Identify-Version
name: Identify the version to be released
with:
ssh-key: ${{ secrets.POSTGREST_SSH_KEY }}
- name: Tag latest commit
run: |
tag_version="${GITHUB_REF##*/}"
cabal_version="$(grep -oP '^version:\s*\K.*' postgrest.cabal)"
if [ "$tag_version" != "v$cabal_version" ]; then
echo "Tagged version ($tag_version) does not match the one in postgrest.cabal (v$cabal_version). Aborting release..."
exit 1
if [[ "$cabal_version" == *.*.* ]]; then
git tag "v$cabal_version"
git push origin "v$cabal_version"
else
echo "Version to be released is $cabal_version"
echo "version=$cabal_version" >> "$GITHUB_OUTPUT"
git tag -f "devel"
git push -f origin "devel"
fi
if [[ "$cabal_version" != *.*.*.* ]]; then
echo "Version is for a full release (version does not have four components)"
else
echo "Version is for a pre-release (version has four components, e.g., 1.1.1.1)"
echo "isprerelease=1" >> "$GITHUB_OUTPUT"
prepare:
name: Release / Prepare
if: |
startsWith(github.ref, 'refs/tags/') &&
needs.docs.result == 'success' &&
needs.test.result == 'success' &&
needs.build.result == 'success' &&
(needs.arm.result == 'skipped' || success())
runs-on: ubuntu-22.04
needs:
- docs
- test
- build
- arm
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
- name: Check the version to be released
run: |
cabal_version="$(grep -oP '^version:\s*\K.*' postgrest.cabal)"
if [ "${GITHUB_REF_NAME}" != "devel" ] && [ "${GITHUB_REF_NAME}" != "v$cabal_version" ]; then
echo "Tagged version ($GITHUB_REF_NAME) does not match the one in postgrest.cabal (v$cabal_version). Aborting release..."
exit 1
fi
- name: Identify changes from CHANGELOG.md
run: |
version="${{ steps.Identify-Version.outputs.version }}"
isprerelease="${{ steps.Identify-Version.outputs.isprerelease }}"
if [ -n "$isprerelease" ]; then
if [ "${GITHUB_REF_NAME}" == "devel" ]; then
echo "Getting unreleased changes..."
sed -n "1,/## Unreleased/d;/## \[/q;p" CHANGELOG.md > CHANGES.md
else
Expand All @@ -164,9 +183,9 @@ jobs:
permissions:
contents: write
runs-on: ubuntu-22.04
needs: prepare
env:
VERSION: ${{ needs.prepare.outputs.version }}
needs:
- prepare
if: success() || needs.prepare.result == 'success'
steps:
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
- name: Download all artifacts
Expand All @@ -179,19 +198,19 @@ jobs:
mkdir -p release-bundle
tar cJvf "release-bundle/postgrest-v$VERSION-linux-static-x64.tar.xz" \
tar cJvf "release-bundle/postgrest-${GITHUB_REF_NAME}-linux-static-x64.tar.xz" \
-C artifacts/postgrest-linux-static-x64 postgrest
tar cJvf "release-bundle/postgrest-v$VERSION-macos-x64.tar.xz" \
tar cJvf "release-bundle/postgrest-${GITHUB_REF_NAME}-macos-x64.tar.xz" \
-C artifacts/postgrest-macos-x64 postgrest
tar cJvf "release-bundle/postgrest-v$VERSION-freebsd-x64.tar.xz" \
tar cJvf "release-bundle/postgrest-${GITHUB_REF_NAME}-freebsd-x64.tar.xz" \
-C artifacts/postgrest-freebsd-x64 postgrest
tar cJvf "release-bundle/postgrest-v$VERSION-ubuntu-aarch64.tar.xz" \
tar cJvf "release-bundle/postgrest-${GITHUB_REF_NAME}-ubuntu-aarch64.tar.xz" \
-C artifacts/postgrest-ubuntu-aarch64 postgrest
zip "release-bundle/postgrest-v$VERSION-windows-x64.zip" \
zip "release-bundle/postgrest-${GITHUB_REF_NAME}-windows-x64.zip" \
artifacts/postgrest-windows-x64/postgrest.exe
- name: Save release bundle
Expand All @@ -205,11 +224,14 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
isprerelease="${{ needs.prepare.outputs.isprerelease }}"
echo "Releasing version v$VERSION on GitHub (isprerelease=$isprerelease)..."
echo "Releasing version ${GITHUB_REF_NAME} on GitHub..."
if [ "${GITHUB_REF_NAME}" == "devel" ]; then
isprerelease=1
fi
gh release delete "v$VERSION" || true
gh release create "v$VERSION" \
gh release delete "${GITHUB_REF_NAME}" || true
gh release create "${GITHUB_REF_NAME}" \
-F artifacts/release-changes/CHANGES.md \
${isprerelease:+"--prerelease"} \
release-bundle/*
Expand All @@ -220,13 +242,13 @@ jobs:
runs-on: ubuntu-22.04
needs:
- prepare
if: |
vars.DOCKER_USER &&
(success() || needs.prepare.result == 'success')
env:
GITHUB_COMMIT: ${{ github.sha }}
DOCKER_REPO: postgrest
DOCKER_USER: stevechavez
DOCKER_PASS: ${{ secrets.DOCKER_PASS }}
VERSION: ${{ needs.prepare.outputs.version }}
ISPRERELEASE: ${{ needs.prepare.outputs.isprerelease }}
steps:
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
- name: Setup Nix Environment
Expand All @@ -243,16 +265,16 @@ jobs:
docker login -u "$DOCKER_USER" -p "$DOCKER_PASS"
docker load -i postgrest-docker.tar.gz
docker tag postgrest:latest "$DOCKER_REPO/postgrest:v$VERSION"
docker push "$DOCKER_REPO/postgrest:v$VERSION"
docker tag postgrest:latest "$DOCKER_REPO/postgrest:${GITHUB_REF_NAME}"
docker push "$DOCKER_REPO/postgrest:${GITHUB_REF_NAME}"
# Only tag 'latest' for full releases
if [[ -z "$ISPRERELEASE" ]]; then
echo "Pushing to 'latest' tag for full release of v$VERSION ..."
if [ "${GITHUB_REF_NAME}" != "devel" ]; then
echo "Pushing to 'latest' tag for full release of ${GITHUB_REF_NAME} ..."
docker tag postgrest:latest "$DOCKER_REPO"/postgrest:latest
docker push "$DOCKER_REPO"/postgrest:latest
else
echo "Skipping pushing to 'latest' tag for v$VERSION pre-release..."
echo "Skipping push to 'latest' tag for pre-release..."
fi
# TODO: Enable dockerhub description update again, once a solution for the permission problem is found:
# https://github.com/docker/hub-feedback/issues/1927
Expand All @@ -273,15 +295,12 @@ jobs:
runs-on: ubuntu-22.04
needs:
- arm
- prepare
- docker
env:
GITHUB_COMMIT: ${{ github.sha }}
DOCKER_REPO: postgrest
DOCKER_USER: stevechavez
DOCKER_PASS: ${{ secrets.DOCKER_PASS }}
VERSION: ${{ needs.prepare.outputs.version }}
ISPRERELEASE: ${{ needs.prepare.outputs.isprerelease }}
steps:
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
- name: Publish images for ARM builds on Docker Hub
Expand All @@ -294,8 +313,8 @@ jobs:
key: ${{ secrets.SSH_ARM_PRIVATE_KEY }}
fingerprint: ${{ secrets.SSH_ARM_FINGERPRINT }}
script_stop: true
envs: GITHUB_COMMIT,DOCKER_REPO,DOCKER_USER,DOCKER_PASS,REMOTE_DIR,VERSION,ISPRERELEASE
script: bash ~/$REMOTE_DIR/docker-publish.sh "$GITHUB_COMMIT" "$DOCKER_REPO" "$DOCKER_USER" "$DOCKER_PASS" "$REMOTE_DIR" "$VERSION" "$ISPRERELEASE"
envs: GITHUB_COMMIT,DOCKER_REPO,DOCKER_USER,DOCKER_PASS,REMOTE_DIR,GITHUB_REF_NAME
script: bash ~/$REMOTE_DIR/docker-publish.sh "$GITHUB_COMMIT" "$DOCKER_REPO" "$DOCKER_USER" "$DOCKER_PASS" "$REMOTE_DIR" "$GITHUB_REF_NAME"


clean-arm:
Expand Down

0 comments on commit e20388a

Please sign in to comment.