From 44b600df2296aef5381cd638d9cecbbde7448beb Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Wed, 16 Sep 2026 18:29:27 +0530 Subject: [PATCH] OpenConceptLab/ocl_issues#2733 | GHA to create release, tag and generate changelog --- .github/workflows/build.yml | 94 ++++++++----------------- Dockerfile | 2 +- release_version.sh | 133 ++++++++++++++++++++++++++++-------- set_build_version.sh | 3 +- 4 files changed, 134 insertions(+), 98 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a93f23372..5e7a885f5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,6 +4,9 @@ on: push: branches: [ "master" ] +permissions: + contents: write + env: AWS_REGION: "us-east-2" # set this to your preferred AWS region, e.g. us-west-1 ECR_REPOSITORY: "oclapi2" # set this to your Amazon ECR repository name @@ -154,18 +157,11 @@ jobs: swap-storage: false - name: Checkout repo uses: actions/checkout@v3 - - name: Add GITHUB_SHA_SHORT env property with commit short sha - run: echo "GITHUB_SHA_SHORT=`echo ${GITHUB_SHA} | cut -c1-8`" >> $GITHUB_ENV - - name: Add VERSION to env property + - name: Compute version and short sha + id: version run: | - VERSION=$(cat core/__init__.py \ - | grep API_VERSION \ - | head -1 \ - | awk -F= '{ print $2 }' \ - | sed "s/[',]//g" \ - | tr -d '[[:space:]]') - echo $VERSION - echo "VERSION=$VERSION" >> $GITHUB_ENV + echo "tag=$(bash release_version.sh full-version)" >> $GITHUB_OUTPUT + echo "sha=$(bash release_version.sh sha)" >> $GITHUB_OUTPUT - name: Log in to Docker Hub uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a with: @@ -178,15 +174,15 @@ jobs: with: context: . push: true - tags: openconceptlab/oclapi2:nightly, openconceptlab/oclapi2:${{ env.VERSION }}-${{env.GITHUB_SHA_SHORT}} - build-args: SOURCE_COMMIT=${{env.GITHUB_SHA_SHORT}} + tags: openconceptlab/oclapi2:nightly, openconceptlab/oclapi2:${{ steps.version.outputs.tag }} + build-args: SOURCE_COMMIT=${{ steps.version.outputs.sha }} cache-from: type=gha cache-to: type=gha,mode=min release: needs: [build] runs-on: ubuntu-latest - name: Release draft + name: Release environment: rc steps: - name: Free Disk Space @@ -201,24 +197,12 @@ jobs: swap-storage: false - name: Checkout repo uses: actions/checkout@v3 - - name: Add GITHUB_SHA_SHORT env property with commit short sha - run: echo "GITHUB_SHA_SHORT=`echo ${GITHUB_SHA} | cut -c1-8`" >> $GITHUB_ENV - - name: Add VERSION to env property - run: | - VERSION=$(cat core/__init__.py \ - | grep API_VERSION \ - | head -1 \ - | awk -F= '{ print $2 }' \ - | sed "s/[',]//g" \ - | tr -d '[[:space:]]') - echo "VERSION=$VERSION" >> $GITHUB_ENV - - name: Tag and release - uses: avakar/tag-and-release@v1 - with: - tag_name: ${{ env.VERSION }}-${{env.GITHUB_SHA_SHORT}} - draft: true + with: + fetch-depth: 0 + - name: Publish release and bump version + run: bash release_version.sh publish env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} deploy-qa: needs: [release] @@ -238,22 +222,14 @@ jobs: uses: aws-actions/amazon-ecr-login@v1 - name: Checkout repo uses: actions/checkout@v3 - - name: Add GITHUB_SHA_SHORT env property with commit short sha - run: echo "GITHUB_SHA_SHORT=`echo ${GITHUB_SHA} | cut -c1-8`" >> $GITHUB_ENV - - name: Add VERSION to env property - run: | - VERSION=$(cat core/__init__.py \ - | grep API_VERSION \ - | head -1 \ - | awk -F= '{ print $2 }' \ - | sed "s/[',]//g" \ - | tr -d '[[:space:]]') - echo "VERSION=$VERSION" >> $GITHUB_ENV + - name: Compute version and short sha + id: version + run: echo "tag=$(bash release_version.sh full-version)" >> $GITHUB_OUTPUT - name: Push image to Amazon ECR id: push-image env: ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} - IMAGE_TAG: ${{ env.VERSION }}-${{env.GITHUB_SHA_SHORT}} + IMAGE_TAG: ${{ steps.version.outputs.tag }} run: | # Build a docker container and # push it to ECR so that it can @@ -410,22 +386,14 @@ jobs: uses: aws-actions/amazon-ecr-login@v1 - name: Checkout repo uses: actions/checkout@v3 - - name: Add GITHUB_SHA_SHORT env property with commit short sha - run: echo "GITHUB_SHA_SHORT=`echo ${GITHUB_SHA} | cut -c1-8`" >> $GITHUB_ENV - - name: Add VERSION to env property - run: | - VERSION=$(cat core/__init__.py \ - | grep API_VERSION \ - | head -1 \ - | awk -F= '{ print $2 }' \ - | sed "s/[',]//g" \ - | tr -d '[[:space:]]') - echo "VERSION=$VERSION" >> $GITHUB_ENV + - name: Compute version and short sha + id: version + run: echo "tag=$(bash release_version.sh full-version)" >> $GITHUB_OUTPUT - name: Push image to Amazon ECR id: push-image env: ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} - IMAGE_TAG: ${{ env.VERSION }}-${{env.GITHUB_SHA_SHORT}} + IMAGE_TAG: ${{ steps.version.outputs.tag }} run: | # Build a docker container and # push it to ECR so that it can @@ -580,22 +548,14 @@ jobs: uses: aws-actions/amazon-ecr-login@v1 - name: Checkout repo uses: actions/checkout@v3 - - name: Add GITHUB_SHA_SHORT env property with commit short sha - run: echo "GITHUB_SHA_SHORT=`echo ${GITHUB_SHA} | cut -c1-8`" >> $GITHUB_ENV - - name: Add VERSION to env property - run: | - VERSION=$(cat core/__init__.py \ - | grep API_VERSION \ - | head -1 \ - | awk -F= '{ print $2 }' \ - | sed "s/[',]//g" \ - | tr -d '[[:space:]]') - echo "VERSION=$VERSION" >> $GITHUB_ENV + - name: Compute version and short sha + id: version + run: echo "tag=$(bash release_version.sh full-version)" >> $GITHUB_OUTPUT - name: Push image to Amazon ECR id: push-image env: ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} - IMAGE_TAG: ${{ env.VERSION }}-${{env.GITHUB_SHA_SHORT}} + IMAGE_TAG: ${{ steps.version.outputs.tag }} run: | # Build a docker container and # push it to ECR so that it can diff --git a/Dockerfile b/Dockerfile index e0bd613e2..b94aa5a35 100644 --- a/Dockerfile +++ b/Dockerfile @@ -47,7 +47,7 @@ RUN python manage.py collectstatic --noinput USER ocl -RUN chmod +x set_build_version.sh wait_for_it.sh startup.sh start_celery_worker.sh ping_celery_worker.sh start_flower.sh +RUN chmod +x set_build_version.sh release_version.sh wait_for_it.sh startup.sh start_celery_worker.sh ping_celery_worker.sh start_flower.sh ARG SOURCE_COMMIT diff --git a/release_version.sh b/release_version.sh index 18451f048..71534f3df 100755 --- a/release_version.sh +++ b/release_version.sh @@ -1,43 +1,120 @@ #!/bin/bash -set -e +# Repo-agnostic release helper. Copy this file as-is into any OCL repo and +# only edit the two config lines below. +# +# Version format: RELEASE.MAJOR.MINOR[-channel], e.g. "3.0.0-alpha". +# RELEASE and MAJOR (the first two numbers) and the channel label are set by +# hand by editing VERSION_FILE. MINOR (the third number) plus the trailing +# short commit sha are computed and bumped automatically by `publish`. +# +# Usage: +# ./release_version.sh sha [raw-sha] print an 8-char short sha (raw-sha, else $GITHUB_SHA, else git HEAD, else "dev") +# ./release_version.sh current print the version currently in VERSION_FILE +# ./release_version.sh full-version print "-" +# ./release_version.sh publish create a published GitHub Release with a changelog for the current +# version, then bump MINOR in VERSION_FILE and push the bump commit +set -euo pipefail +# --- Per-repo config (only these two lines differ across repos) --- VERSION_FILE="core/__init__.py" +VERSION_KEY="API_VERSION" +# -------------------------------------------------------------- -SOURCE_COMMIT=$(git rev-parse HEAD) -export SOURCE_COMMIT=${SOURCE_COMMIT:0:8} +cmd_sha() { + local raw="${1:-}" + [ -n "$raw" ] || raw="${GITHUB_SHA:-}" + [ -n "$raw" ] || raw="$(git rev-parse HEAD 2>/dev/null || true)" + [ -n "$raw" ] || raw="dev" + echo "${raw:0:8}" +} -PROJECT_VERSION=$(cat $VERSION_FILE \ - | grep API_VERSION \ - | head -1 \ - | awk -F= '{ print $2 }' \ - | sed "s/[',]//g" \ - | tr -d '[[:space:]]') +cmd_current() { + grep -m1 "$VERSION_KEY" "$VERSION_FILE" \ + | sed -E "s/.*[\"']([0-9]+\.[0-9]+\.[0-9]+[^\"']*)[\"'].*/\1/" +} -TAG="$PROJECT_VERSION-$SOURCE_COMMIT" +cmd_full_version() { + echo "$(cmd_current)-$(cmd_sha)" +} -./set_build_version.sh +next_version() { + local current="$1" release major rest leading suffix + release=$(cut -d. -f1 <<<"$current") + major=$(cut -d. -f2 <<<"$current") + rest=$(cut -d. -f3- <<<"$current") + if [[ "$rest" =~ ^([0-9]+)(.*)$ ]]; then + leading="${BASH_REMATCH[1]}" + suffix="${BASH_REMATCH[2]}" + else + leading=0 + suffix="" + fi + echo "${release}.${major}.$((leading + 1))${suffix}" +} -git checkout -b release -git add $VERSION_FILE -git commit -m "Release version $PROJECT_VERSION" +is_prerelease() { + local current="$1" rest + rest=$(cut -d. -f3- <<<"$current") + [[ "$rest" =~ ^[0-9]+(.*)$ ]] && [ -n "${BASH_REMATCH[1]}" ] +} -git tag "$TAG" +write_version() { + local new_version="$1" + sed -i -E "0,/${VERSION_KEY}/ s/([\"'])[0-9]+\.[0-9]+\.[0-9]+[^\"']*([\"'])/\1${new_version}\2/" "$VERSION_FILE" +} -git remote set-url origin ${GIT_REPO_URL} -git push origin --tags +cmd_publish() { + local current_version sha tag prev_tag changelog new_version default_branch prerelease_args=() -docker pull $DOCKER_IMAGE_ID -docker tag $DOCKER_IMAGE_ID $DOCKER_IMAGE_NAME:$TAG -docker push $DOCKER_IMAGE_NAME:$TAG + current_version="$(cmd_current)" + sha="$(cmd_sha "${GITHUB_SHA:-}")" + tag="${current_version}-${sha}" -if [[ "$INCREASE_MAINTENANCE_VERSION" = true ]]; then - git checkout master + git fetch --tags --quiet || true + prev_tag="$(git describe --tags --abbrev=0 2>/dev/null || true)" + if [ -n "$prev_tag" ]; then + changelog="$(git log "${prev_tag}..HEAD" --pretty=format:'- %s (%h)')" + else + changelog="$(git log --pretty=format:'- %s (%h)')" + fi + [ -n "$changelog" ] || changelog="No changes recorded." - NEW_PROJECT_VERSION=$(echo "${PROJECT_VERSION}" | awk -F. -v OFS=. '{$NF++;print}') - sed -i "s/API_VERSION = '$PROJECT_VERSION'/API_VERSION = '$NEW_PROJECT_VERSION'/" $VERSION_FILE + is_prerelease "$current_version" && prerelease_args=(--prerelease) - git add $VERSION_FILE - git commit -m "[skip ci] Increase maintenance version to $NEW_PROJECT_VERSION" + echo "Publishing release ${tag}" + gh release create "$tag" \ + --target "${GITHUB_SHA:-HEAD}" \ + --title "$tag" \ + --notes "$changelog" \ + "${prerelease_args[@]}" - git push origin master -fi + new_version="$(next_version "$current_version")" + echo "Bumping version: ${current_version} -> ${new_version}" + + default_branch="${GITHUB_REF_NAME:-main}" + git config user.email "github-actions[bot]@users.noreply.github.com" + git config user.name "github-actions[bot]" + git fetch origin "$default_branch" --quiet + git checkout -B "$default_branch" "origin/${default_branch}" + + write_version "$new_version" + git add "$VERSION_FILE" + git commit -m "[skip ci] Bump version to ${new_version}" + + for attempt in 1 2 3; do + if git push origin "$default_branch"; then + break + fi + echo "Push rejected, rebasing and retrying (${attempt})..." + git fetch origin "$default_branch" --quiet + git rebase "origin/${default_branch}" + done +} + +case "${1:-}" in + sha) shift; cmd_sha "${1:-}" ;; + current) cmd_current ;; + full-version) cmd_full_version ;; + publish) cmd_publish ;; + *) echo "Usage: $0 {sha [raw-sha]|current|full-version|publish}" >&2; exit 1 ;; +esac diff --git a/set_build_version.sh b/set_build_version.sh index f36e3cc85..9454f4d9b 100755 --- a/set_build_version.sh +++ b/set_build_version.sh @@ -4,8 +4,7 @@ set -e CONFIG_FILE="core/__init__.py" -SHA=${SOURCE_COMMIT:-'dev'} -SHA=${SHA:0:8} +SHA=$(./release_version.sh sha "${SOURCE_COMMIT:-}") echo "Setting build version to $SHA in $CONFIG_FILE"