From e43e783557100a4eb3466524cfb5c539fa30eeea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Utu=20K=C3=A4rki?= Date: Fri, 19 Apr 2024 14:58:41 +0300 Subject: [PATCH] Add release workflow --- .github/workflows/dev-release.yml | 36 +++++++++++++++ .github/workflows/manual-prod-release.yml | 50 +++++++++++++++++++++ README.md | 6 +++ dev-release.sh | 53 +++++++++++++++++++++++ release.sh | 24 ++++++++++ 5 files changed, 169 insertions(+) create mode 100644 .github/workflows/dev-release.yml create mode 100644 .github/workflows/manual-prod-release.yml create mode 100755 dev-release.sh create mode 100755 release.sh diff --git a/.github/workflows/dev-release.yml b/.github/workflows/dev-release.yml new file mode 100644 index 0000000..bf547d6 --- /dev/null +++ b/.github/workflows/dev-release.yml @@ -0,0 +1,36 @@ +name: 'Dev Release' + +on: + push: + tags: '**' + +jobs: + dev-release: + name: Release to private ECR + runs-on: ubuntu-latest + permissions: + id-token: write + contents: read + steps: + - name: Checkout repo + uses: actions/checkout@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::${{ secrets.UTILITY_ACCOUNT_ID }}:role/Digabi2PrivateEcrGithubActionsAccessRole + aws-region: eu-north-1 + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Build and push + uses: docker/build-push-action@v5 + with: + push: true + tags: ${{ steps.login-ecr.outputs.registry }}/drawio:${{ github.ref_name }} + provenance: false + cache-from: type=gha + cache-to: type=gha,mode=max \ No newline at end of file diff --git a/.github/workflows/manual-prod-release.yml b/.github/workflows/manual-prod-release.yml new file mode 100644 index 0000000..148530e --- /dev/null +++ b/.github/workflows/manual-prod-release.yml @@ -0,0 +1,50 @@ +name: 'Manual Production Release' + +on: + workflow_dispatch: + inputs: + tag: + description: "Tag" + required: true + type: string + +jobs: + release: + name: Release private image to public ECR + runs-on: ubuntu-latest + permissions: + id-token: write + contents: write + steps: + - name: Checkout repo + uses: actions/checkout@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::${{ secrets.UTILITY_ACCOUNT_ID }}:role/Digabi2PrivateEcrGithubActionsAccessRole + aws-region: eu-north-1 + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v2 + - name: Pull private image + run: docker pull ${{ steps.login-ecr.outputs.registry }}/drawio:${{ inputs.tag }} + - name: Configure Public ECR AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::${{ secrets.UTILITY_ACCOUNT_ID }}:role/Digabi2PublicEcrGithubActionsAccessRole + aws-region: us-east-1 + - name: Login to Amazon ECR + id: login-public-ecr + uses: aws-actions/amazon-ecr-login@v2 + with: + registry-type: public + - name: Tag image + run: docker tag ${{ steps.login-ecr.outputs.registry }}/drawio:${{ inputs.tag }} ${{ steps.login-public-ecr.outputs.registry }}/u3p9b9p9/drawio-public:${{ inputs.tag }} + - name: Push image + run: docker push ${{ steps.login-public-ecr.outputs.registry }}/u3p9b9p9/drawio-public:${{ inputs.tag }} + - name: Create Github Release + uses: softprops/action-gh-release@9d7c94cfd0a1f3ed45544c887983e9fa900f0564 # Pin to commit hash to prevent compromise of third party action + with: + tag_name: ${{ inputs.tag }} diff --git a/README.md b/README.md index 9102876..72cc664 100644 --- a/README.md +++ b/README.md @@ -11,3 +11,9 @@ git submodule update npm run docker:build npm run docker:run ``` + +## Release + +To release a development version, run `./release.sh >`. This builds and pushes a new image to the private ECR. + +To promote a development version to production (i.e. publish a private image to the public ECR), run `./release.sh` which lets you select the image tag you wish to promote. This also generates a Github release. \ No newline at end of file diff --git a/dev-release.sh b/dev-release.sh new file mode 100755 index 0000000..06eea5a --- /dev/null +++ b/dev-release.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash + +BRANCH_TO_RELEASE_FROM="main" +FILES_TO_INCLUDE_IN_RELEASE_COMMITS="package.json package-lock.json" + +# Show help message if no arguments are given or -h/--help flag is used +if [ "$#" -eq 0 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then + echo "Usage: release.sh < major | minor | patch | >" + echo "Example: release.sh patch, bumps up the third number in the version" + exit 0 +fi + +# check argument is major, minor or patch or semver, we don't want pre-tags +if [ "$1" != "major" ] && [ "$1" != "minor" ] && [ "$1" != "patch" ] && ! [[ "$1" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Invalid argument. Use major, minor, patch or semver (..) version." + exit 1 +fi + +# Check git branch and abort if not on correct release branch +CURRENT_BRANCH=$(git branch --show-current) +if [ "$CURRENT_BRANCH" != "$BRANCH_TO_RELEASE_FROM" ]; then + echo "You are on branch $CURRENT_BRANCH. Releases only from $BRANCH_TO_RELEASE_FROM branch." + exit 1 +fi + +echo "" +OLD_NPM_VERSION=v$(npm pkg get version | tr -d \") # version is printed without v prefix, so it is added here +echo "Old version: $OLD_NPM_VERSION" + +NEW_NPM_VERSION=$(npm version --git-tag-version=false "$1") +echo "New version: $NEW_NPM_VERSION" + + +echo "" +echo "Do you want to commit, tag and push the above changes? (y/n)" +read -r answer + +# Commit and push changes if the user answered y +if [ "$answer" = "y" ]; then + git add "$FILES_TO_INCLUDE_IN_RELEASE_COMMITS" + git commit -m "Release $NEW_NPM_VERSION" + if ! git tag -m "Release $NEW_NPM_VERSION" "$NEW_NPM_VERSION"; then + git reset --soft HEAD~1 + echo "Failed to create tag $NEW_NPM_VERSION. Release aborted and commit reverted." + exit 1 + fi + echo "" + git push --atomic origin $BRANCH_TO_RELEASE_FROM "$NEW_NPM_VERSION" + echo "" + echo "Release commit and tag $NEW_NPM_VERSION pushed." +else + echo "Release aborted. Please revert incorrect changes." +fi diff --git a/release.sh b/release.sh new file mode 100755 index 0000000..f60da4b --- /dev/null +++ b/release.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +# Get all tags from the remote repository and save them to a variable, in short format +tags=$(git ls-remote --tags --refs origin | awk '{print $2}' | awk -F"/" '{print $3}') + +released=$(gh release list --json tagName --jq ".[].tagName") +# filter out the tags that have not been released +unreleased_tags=$(echo "$tags" "$released" | tr ' ' '\n' | sort | uniq -u) + +# make tags an selectable list +# check if fzf is installed +if ! command -v fzf &> /dev/null +then + echo -e "Install fzf for a nicer selection experience\n" + echo "Unreleased tags:" + echo "$unreleased_tags" + read -r -p "Enter tag to release: " tag_to_release +else + tag_to_release=$(echo "$unreleased_tags" | tr ' ' '\n' | fzf --prompt="Select tag to release: ") +fi + +echo "Running release workflow for "$tag_to_release"" +# using github cli trigger manual workflow with the tag to release as the tag parameter +gh workflow run manual-prod-release.yml -f tag="$tag_to_release"