Skip to content

Prepare Release

Prepare Release #7

name: "Prepare Release"
on:
workflow_dispatch:
inputs:
branch:
description: "The Branch to Release From"
required: false
default: "main"
release-version:
description: "The Version to Release"
required: false
env:
CI_BUILD_WORKFLOW: "continuous-integration.yaml" # Name of the workflow that should be triggered for CI build
RELEASE_ARTIFACT_NAME: "release-artifacts" # Name of the artifact that should be downloaded from the CI workflow
SDK_TARGETS_NAME: "sdk-targets" # Name of the SDK target directories artifact that should be downloaded from the CI workflow
DOCS_REPO: SAP/cloud-sdk
jobs:
bump-version:
name: "Bump Version"
outputs:
current-version: ${{ steps.determine-versions.outputs.CURRENT_SNAPSHOT }}
release-version: ${{ steps.determine-versions.outputs.RELEASE_VERSION }}
new-version: ${{ steps.determine-versions.outputs.NEW_SNAPSHOT }}
release-branch: ${{ steps.prepare-release.outputs.BRANCH_NAME }}
release-commit: ${{ steps.prepare-release.outputs.RELEASE_COMMIT_ID }}
release-tag: ${{ steps.prepare-release.outputs.TAG_NAME }}
runs-on: ubuntu-latest
steps:
- name: "Checkout Repository"
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.branch }}
token: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }} # this is needed so that the same token is used when pushing our changes later. Otherwise, our on: push workflows (i.e. our continuous integration) won't be triggered.
- name: "Determine Versions"
id: determine-versions
run: python .pipeline/scripts/get-release-versions.py
env:
INPUT_VERSION: ${{ github.event.inputs.release-version }}
- run: "echo Release Version: ${{ steps.determine-versions.outputs.RELEASE_VERSION }}"
- run: "echo Current Version: ${{ steps.determine-versions.outputs.CURRENT_SNAPSHOT }}"
- run: "echo New Version: ${{ steps.determine-versions.outputs.NEW_SNAPSHOT }}"
- name: "Prepare git"
run: |
git config --global user.email "[email protected]"
git config --global user.name "SAP Cloud SDK Bot"
- name: "Set Release Version to ${{ steps.determine-versions.outputs.RELEASE_VERSION }}"
id: prepare-release
run: |
# NOTE: If you change this pattern here, also adjust perform_release.yml:
BRANCH_NAME=RELEASE-${{ steps.determine-versions.outputs.RELEASE_VERSION }}
echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_OUTPUT
git switch --create $BRANCH_NAME
python .pipeline/scripts/set-release-versions.py --version ${{ steps.determine-versions.outputs.RELEASE_VERSION }}
git add .
git commit -m "Update to version ${{ steps.determine-versions.outputs.RELEASE_VERSION }}"
# We need to get the commit id, and push the branch so the release tag will point at the right commit afterwards
RELEASE_COMMIT_ID=$(git log -1 --pretty=format:"%H")
echo "RELEASE_COMMIT_ID=$RELEASE_COMMIT_ID" >> $GITHUB_OUTPUT
TAG_NAME=rel/${{ steps.determine-versions.outputs.RELEASE_VERSION }}
git tag $TAG_NAME $RELEASE_COMMIT_ID
echo "TAG_NAME=$TAG_NAME" >> $GITHUB_OUTPUT
git push origin $BRANCH_NAME
git push origin $TAG_NAME
run-ci:
name: "Continuous Integration"
outputs:
ci-run-id: ${{ steps.trigger-ci.outputs.run-id }}
needs: [ bump-version ]
runs-on: ubuntu-latest
permissions:
actions: write # needed to trigger the ci-build workflow
statuses: write # needed to update the commit status
steps:
- name: "Checkout repository"
uses: actions/checkout@v4
with:
ref: ${{ needs.bump-version.outputs.release-branch }}
- name: "Trigger CI Workflow"
id: trigger-ci
uses: ./.github/actions/trigger-workflow
with:
workflow: ${{ env.CI_BUILD_WORKFLOW }}
workflow-ref: ${{ needs.bump-version.outputs.release-branch }}
commit-sha: ${{ needs.bump-version.outputs.release-commit }}
parameters: >
-f commit=${{ needs.bump-version.outputs.release-commit }}
-f build-release-artifacts=true
-f sign-release-artifacts=true
-f run-blackduck-scan=true
-f run-security-rating=true
- name: "Await CI Workflow"
uses: ./.github/actions/await-workflow
with:
run-id: ${{ steps.trigger-ci.outputs.run-id }}
commit-status: "Continuous Integration Workflow"
create-release:
name: "Create GitHub Release"
needs: [ bump-version, run-ci ]
outputs:
release-name: ${{ steps.create-release.outputs.RELEASE_NAME }}
release-url: ${{ steps.create-release.outputs.RELEASE_URL }}
permissions:
contents: write # needed to create a new release
actions: read # needed to download the artifacts from the CI workflow
runs-on: ubuntu-latest
steps:
- name: "Checkout repository"
uses: actions/checkout@v4
with:
ref: ${{ needs.bump-version.outputs.release-branch }}
- name: "Download Release Artifacts"
uses: actions/download-artifact@v4
with:
name: ${{ env.RELEASE_ARTIFACT_NAME }}
github-token: ${{ github.token }}
run-id: ${{ needs.run-ci.outputs.ci-run-id }}
path: .release-artifacts/
# needed to get the aggregated JavaDocs
- name: "Download SDK Targets"
uses: actions/download-artifact@v4
with:
name: ${{ env.SDK_TARGETS_NAME }}
github-token: ${{ github.token }}
run-id: ${{ needs.run-ci.outputs.ci-run-id }}
path: .targets/
- name: "Prepare git"
run: |
git config --global user.email "[email protected]"
git config --global user.name "SAP Cloud SDK Bot"
- name: "Create Release"
id: create-release
run: |
tar -caf apidocs-${{ needs.bump-version.outputs.release-version }}.tar.gz -C .targets/target/site/apidocs/ .
tar -caf release-${{ needs.bump-version.outputs.release-version }}.tar.gz -C .release-artifacts/ .
RELEASE_NAME="rel/${{ needs.bump-version.outputs.release-version }}"
echo "RELEASE_NAME=$RELEASE_NAME" >> $GITHUB_OUTPUT
RELEASE_URL=$(gh release create "$RELEASE_NAME" \
--target ${{ needs.bump-version.outputs.release-commit }} \
--title "Release ${{ needs.bump-version.outputs.release-version }}" \
--draft --generate-notes \
apidocs-${{ needs.bump-version.outputs.release-version }}.tar.gz \
release-${{ needs.bump-version.outputs.release-version }}.tar.gz)
echo "RELEASE_URL=$RELEASE_URL" >> $GITHUB_OUTPUT
env:
GH_TOKEN: ${{ github.token }}
create-docs-pr:
name: "Create JavaDocs PR"
needs: [ bump-version, run-ci ]
outputs:
branch: ${{ steps.replace-javadoc.outputs.BRANCH_NAME }}
pr-url: ${{ steps.create-javadoc-pr.outputs.PR_URL }}
runs-on: ubuntu-latest
steps:
- name: "Checkout Code Repository"
uses: actions/checkout@v4
with:
ref: ${{ needs.bump-version.outputs.release-branch }}
- name: "Checkout Docs Repository"
uses: actions/checkout@v4
with:
repository: ${{ env.DOCS_REPO }}
path: .cloud-sdk-docs
token: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }}
# needed to get the aggregated JavaDocs
- name: "Download SDK Targets"
uses: actions/download-artifact@v4
with:
name: ${{ env.SDK_TARGETS_NAME }}
github-token: ${{ github.token }}
run-id: ${{ needs.run-ci.outputs.ci-run-id }}
path: .targets
- name: "Determine Major Version"
id: determine-major-version
run: echo "MAJOR_VERSION=$(jq -r '.version' latest.json | cut -d '.' -f 1)" >> $GITHUB_OUTPUT
- name: "Prepare Git"
working-directory: ./.cloud-sdk-docs
run: |
git config --global user.email "[email protected]"
git config --global user.name "SAP Cloud SDK Bot"
- name: "Replace JavaDoc"
id: replace-javadoc
run: |
TARGET_DIR=./.cloud-sdk-docs/static/java-api/v${{ steps.determine-major-version.outputs.MAJOR_VERSION }}
rm -rf $TARGET_DIR
mkdir -p $TARGET_DIR
mv ./.targets/target/site/apidocs/* $TARGET_DIR
cd ./.cloud-sdk-docs
git add -A .
CHANGED_FILES="$(git status -s)"
if [[ -z "$CHANGED_FILES" ]]; then
echo "[DEBUG] No changes to API docs detected, skipping Pull Request creation."
echo "CREATE_PR=false" >> $GITHUB_OUTPUT
exit 0
fi
echo "CREATE_PR=true" >> $GITHUB_OUTPUT
BRANCH_NAME=java/release-docs-${{ needs.bump-version.outputs.release-version }}
echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_OUTPUT
git switch --create $BRANCH_NAME
git commit -m "chore: Update JavaDocs for release ${{ needs.bump-version.outputs.release-version }}"
COMMIT_SHA=$(git log -1 --pretty=format:"%H")
echo "COMMIT_SHA=$COMMIT_SHA" >> $GITHUB_OUTPUT
git push origin $BRANCH_NAME
- name: "Create JavaDoc PR"
id: create-javadoc-pr
if: ${{ steps.replace-javadoc.outputs.CREATE_PR == 'true' }}
working-directory: ./.cloud-sdk-docs
run: |
PR_TITLE="Java: Update JavaDocs for release ${{ needs.bump-version.outputs.release-version }}"
PR_BODY="Replace the contents of v${{ steps.determine-major-version.outputs.MAJOR_VERSION }} API docs with the latest release of the SDK."
PR_URL=$(gh pr create --title "$PR_TITLE" --body "$PR_BODY" --repo "${{ env.DOCS_REPO }}")
echo "PR_URL=$PR_URL" >> $GITHUB_OUTPUT
env:
GH_TOKEN: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }}
create-release-notes-pr:
name: "Create Release Notes PR"
needs: [ bump-version, run-ci ]
outputs:
pr-url: ${{ steps.create-release-notes-pr.outputs.PR_URL }}
runs-on: ubuntu-latest
steps:
- name: "Checkout Code Repository"
uses: actions/checkout@v4
with:
ref: ${{ needs.bump-version.outputs.release-branch }}
token: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }}
- name: "Checkout Docs Repository"
uses: actions/checkout@v4
with:
repository: ${{ env.DOCS_REPO }}
path: .cloud-sdk-docs
token: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }}
- name: "Prepare Git"
working-directory: ./.cloud-sdk-docs
run: |
git config --global user.email "[email protected]"
git config --global user.name "SAP Cloud SDK Bot"
- name: "Create Release Notes Branch"
working-directory: ./.cloud-sdk-docs
run: git checkout -B java/release-notes-${{ needs.bump-version.outputs.release-version }}
- name: "Create Release Notes"
run: python .pipeline/scripts/release_notes_automation.py --version ${{ needs.bump-version.outputs.release-version }} --folder ".cloud-sdk-docs/docs-java/release-notes"
- name: "Commit Release Notes"
working-directory: ./.cloud-sdk-docs
run: |
git add .
git commit -m "Add new release notes"
- name: "Push Release Notes"
working-directory: ./.cloud-sdk-docs
run: git push origin java/release-notes-${{ needs.bump-version.outputs.release-version }}
- name: "Create Release Notes PR"
id: create-release-notes-pr
working-directory: ./.cloud-sdk-docs
run: |
PR_TITLE="Java: Add release notes for release ${{ needs.bump-version.outputs.release-version }}"
# if the minor version is a multiple of 15, then change the PR_BODY to "# ⚠️Update the `docs-java/release-notes/index.jsx` file⚠️"
# else the PR_BODY will be "Add the SAP Cloud SDK ${{ needs.bump-version.outputs.release-version }} release notes"
minor_version=$(echo ${{ needs.bump-version.outputs.release-version }} | cut -d '.' -f 2)
if [[ $((minor_version % 15)) -eq 0 ]]; then
PR_BODY="# ⚠️Update the \`docs-java/release-notes/index.jsx\` file⚠️"
else
PR_BODY="Add the SAP Cloud SDK ${{ needs.bump-version.outputs.release-version }} release notes"
fi
PR_URL=$(gh pr create --title "$PR_TITLE" --body "$PR_BODY" --repo "${{ env.DOCS_REPO }}")
echo "PR_URL=$PR_URL" >> $GITHUB_OUTPUT
env:
GH_TOKEN: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }}
- name: "Reset Release Notes for Next Version"
run: |
rm -rf .cloud-sdk-docs
cp .pipeline/scripts/release_notes_template.md release_notes.md
git add release_notes.md
CHANGED_FILES="$(git status -s)"
if [[ -z "$CHANGED_FILES" ]]; then
echo "[DEBUG] No changes to release_notes.md detected, skipping reset."
exit 0
fi
git commit -m "Reset release notes"
git push
create-code-pr:
name: "Create Code PR"
needs: [ bump-version, run-ci, create-release, create-docs-pr, create-release-notes-pr ]
outputs:
pr-url: ${{ steps.create-code-pr.outputs.PR_URL }}
runs-on: ubuntu-latest
steps:
- name: "Checkout Repository"
uses: actions/checkout@v4
with:
ref: ${{ needs.bump-version.outputs.release-branch }}
token: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }} # this is needed so that the same token is used when pushing our changes later. Otherwise, our on: push workflows (i.e. our continuous integration) won't be triggered.
- name: "Prepare Git"
run: |
git config --global user.email "[email protected]"
git config --global user.name "SAP Cloud SDK Bot"
- name: "Set New Version"
run: |
python .pipeline/scripts/set-release-versions.py --version ${{ needs.bump-version.outputs.new-version }}
git add .
git commit -m "Update to version ${{ needs.bump-version.outputs.new-version }}"
git push
- name: "Create Code PR"
run: |
COMMIT_URL=${{ github.event.repository.html_url }}/commit/${{ needs.bump-version.outputs.release-commit }}
PR_URL=$(gh pr create --title "Release ${{ needs.bump-version.outputs.release-version }}" --body "## TODOs
- [ ] Review the changes in [the release commit]($COMMIT_URL)
- [ ] Review **and approve** the [Release Notes PR](${{ needs.create-release-notes-pr.outputs.pr-url }})
- [ ] Review **and approve** the [JavaDocs PR](${{ needs.create-docs-pr.outputs.pr-url }})
- [ ] Review the [Draft Release](${{ needs.create-release.outputs.release-url }})
- [ ] Review **and approve** this PR
- [ ] Trigger the [Perform Release Workflow](${{ github.event.repository.html_url }}/actions/workflows/perform-release.yml)
- [ ] Once the `Perform Release` workflow is through, head over to the [OSS Repository](https://oss.sonatype.org/#stagingRepositories) and log in with the credentials in the Team Password Safe. There should be a staged release. Check whether everything looks good and, if so, publish the release.")
echo "PR_URL=$PR_URL" >> $GITHUB_OUTPUT
env:
GH_TOKEN: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }}
handle-failure:
runs-on: ubuntu-latest
needs: [ bump-version, run-ci, create-release, create-docs-pr, create-release-notes-pr, create-code-pr ]
permissions:
contents: write # needed to delete the GitHub release
if: ${{ failure() }}
steps:
- name: "Checkout Repository"
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.branch }}
- name: "Delete Release"
if: ${{ needs.create-release.outputs.release-url != '' }}
run: gh release delete --repo "${{ github.repository }}" ${{ needs.create-release.outputs.release-name }} --yes
env:
GITHUB_TOKEN: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }}
continue-on-error: true
- name: "Delete Release Branch"
if: ${{ needs.bump-version.outputs.release-branch != '' }}
run: git push --delete origin ${{ needs.bump-version.outputs.release-branch }}
env:
GITHUB_TOKEN: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }}
continue-on-error: true
- name: "Delete Release Tag"
if: ${{ needs.bump-version.outputs.release-tag != '' }}
run: git push --delete origin ${{ needs.bump-version.outputs.release-tag }}
env:
GITHUB_TOKEN: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }}
continue-on-error: true
- name: "Delete Docs PR"
if: ${{ needs.create-docs-pr.outputs.pr-url != '' }}
run: gh pr close --repo "${{ env.DOCS_REPO }}" ${{ needs.create-docs-pr.outputs.pr-url }} --delete-branch
env:
GITHUB_TOKEN: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }}
continue-on-error: true
- name: "Delete Release Notes PR"
if: ${{ needs.create-release-notes-pr.outputs.pr-url != '' }}
run: gh pr close --repo "${{ env.DOCS_REPO }}" ${{ needs.create-release-notes-pr.outputs.pr-url }} --delete-branch
env:
GITHUB_TOKEN: ${{ secrets.BOT_SDK_JS_FOR_DOCS_REPO_PR }}
continue-on-error: true
- name: "Notify"
run: python .pipeline/scripts/notify.py
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
WORKFLOW: ${{ github.workflow }}
WORKFLOW_RUN_URL: ${{ github.event.repository.html_url }}/actions/runs/${{ github.run_id }}
BRANCH_NAME: ${{ github.event.inputs.branch }}