diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000000..6495544d43 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,160 @@ +name: "Release" +run-name: Release new ${{ inputs.version-type }} from ${{ github.ref_name }} + +on: + workflow_dispatch: + inputs: + version-type: + description: "Version type" + required: true + type: choice + default: "alpha" + options: + - "alpha" + - "beta" + - "GA" + +jobs: + prepare-version: + runs-on: ubuntu-24.04 + steps: + - uses: actions/create-github-app-token@v1 + id: app-token + with: + app-id: ${{ vars.ACTIONS_APP_ID }} + private-key: ${{ secrets.ACTIONS_APP_PRIVATE_KEY }} + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ steps.app-token.outputs.token }} + - name: Install semver tool + run: | + curl --fail -LO https://raw.githubusercontent.com/fsaintjacques/semver-tool/3.4.0/src/semver + chmod +x ./semver + - name: Compose release tag + run: | + source VERSION + + SHORT_VERSION="$VERSION_MAJOR.$VERSION_MINOR" + BASE_VERSION="$SHORT_VERSION.$VERSION_PATCH" + TAG="$BASE_VERSION" + + if [ "${{ inputs.version-type }}" == "alpha" ] || [ "${{ inputs.version-type }}" == "beta" ] ; then + TAG="$TAG-${{ inputs.version-type }}" + TAG_QUERY="$TAG*" + elif [ "${{ inputs.version-type }}" == "GA" ]; then + TAG_QUERY="$TAG" + else + echo "Invalid release type: ${{ inputs.version-type }}" + exit 1 + fi + + LAST_MATCH_TAG=$(git tag -l --sort=-v:refname "$TAG_QUERY" | head -n 1) + + if [ "${{ inputs.version-type }}" == "GA" ] && [ "$LAST_MATCH_TAG" != "" ]; then + echo "Release $LAST_MATCH_TAG already exists" + exit 1 + fi + + if [ "${{ inputs.version-type }}" == "alpha" ] || [ "${{ inputs.version-type }}" == "beta" ] ; then + SUFFIX_NUMBER="1" + + if [ "$LAST_MATCH_TAG" != "" ]; then + SUFFIX_NUMBER=$(./semver get prerel $LAST_MATCH_TAG | cut -d'.' -f2) + SUFFIX_NUMBER=$((SUFFIX_NUMBER + 1)) + fi + + TAG="$TAG.$SUFFIX_NUMBER" + fi + + echo "SHORT_VERSION=$SHORT_VERSION" >> $GITHUB_ENV + echo "BASE_VERSION=$BASE_VERSION" >> $GITHUB_ENV + echo "RELEASE_TAG=$TAG" >> $GITHUB_ENV + echo "RELEASE_BRANCH=release/$TAG" >> $GITHUB_ENV + - name: Validate ${{ env.RELEASE_TAG }} tag + run: ./semver validate ${{ env.RELEASE_TAG }} + - name: Check if version ${{ env.BASE_VERSION }} is on the right branch + run: | + source VERSION + + # Need to fetch dev branches first + git fetch --no-tags origin HEAD '+refs/heads/development/*:refs/remotes/origin/development/*' + + GIT_REMOTE=$(git remote) + BASE_BRANCH=$(git branch -a --list ${GIT_REMOTE}/development/${VERSION_MAJOR}.${VERSION_MINOR}) + if ! git merge-base --is-ancestor HEAD ${BASE_BRANCH}; then + echo "Version commit is not included in base branch ${BASE_BRANCH}" + exit 1 + fi + - name: Prepare branch + run: git checkout -b ${{ env.RELEASE_BRANCH }} + - name: Set the new version + run: | + if [ -z "${NEW_VERSION_SUFFIX}" ]; then + NEW_VERSION_SUFFIX=$(./semver get prerel ${{ env.RELEASE_TAG }}) + [ -n "$NEW_VERSION_SUFFIX" ] && NEW_VERSION_SUFFIX="-$NEW_VERSION_SUFFIX" + fi + sed -i "s/VERSION_SUFFIX=.*/VERSION_SUFFIX=$NEW_VERSION_SUFFIX/" VERSION + - name: Commit with requested version and push + run: | + git fsck + git gc + git add VERSION + git config --global user.email ${{ github.actor }}@scality.com + git config --global user.name ${{ github.actor }} + git commit -m "Release ${{ env.RELEASE_TAG }}" + git push --set-upstream origin ${{ env.RELEASE_BRANCH }} + - name: Create and push `${{ env.RELEASE_TAG }}` tag + run: | + BODY=$(mktemp) + + cat > $BODY <<- EOM + MetalK8s ${{ env.RELEASE_TAG }} + === + + MetalK8s ${{ env.RELEASE_TAG }} is a patch release (see [the main release ${{ env.BASE_VERSION }}](https://github.com/scality/metalk8s/releases/${{ env.BASE_VERSION }})). + + Useful links + --- + + - [Documentation](https://metal-k8s.readthedocs.io/en/${{ env.RELEASE_TAG }}) + - [Upgrade notes](https://metal-k8s.readthedocs.io/en/${{ env.RELEASE_TAG }}/operation/upgrade.html) + - [Changelog](https://github.com/scality/metalk8s/blob/${{ env.RELEASE_TAG }}/CHANGELOG.md) + + What's new + --- + + EOM + + while IFS= read -r line; do + echo " - $line" >> $BODY + done <<< "$(git log --no-merges --format=%s $(git describe --abbrev=0)..HEAD)" + + git tag -a "${{ env.RELEASE_TAG }}" -F $BODY + git push origin ${{ env.RELEASE_TAG }} + - name: Merge ${{ env.RELEASE_TAG }} tag into ${{ github.ref_name }} branch + run: | + git checkout development/${{ env.SHORT_VERSION }} + git pull + git checkout -b release/merge/${{ env.RELEASE_TAG }} + git merge ${{env.RELEASE_TAG}} --no-ff + + source VERSION + + if [ "${{ inputs.version-type }}" == "GA" ]; then + VERSION_PATCH=$((VERSION_PATCH + 1)) + sed -i "s/VERSION_PATCH=.*/VERSION_PATCH=$VERSION_PATCH/" VERSION + fi + + VERSION_SUFFIX="-dev" + sed -i "s/VERSION_SUFFIX=.*/VERSION_SUFFIX=$VERSION_SUFFIX/" VERSION + + git add VERSION + git commit -m "Bump version to $VERSION_MAJOR.$VERSION_MINOR.$VERSION_PATCH$VERSION_SUFFIX" + git push --set-upstream origin release/merge/${{ env.RELEASE_TAG }} + + git checkout development/${{ env.SHORT_VERSION }} + git pull + git merge release/merge/${{ env.RELEASE_TAG }} --no-ff + git push