🚀 Release Builder #16
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # This workflow will build the project and create a release on demand | |
| # Uses: | |
| # OS: ubuntu-latest | |
| # Go: go 1.x | |
| name: 🚀 Release Builder | |
| on: | |
| schedule: | |
| # Runs every Friday at 12:00 PM IST (6:30 AM UTC) | |
| - cron: '30 6 * * 5' | |
| workflow_dispatch: | |
| inputs: | |
| bump_type: | |
| description: 'Version bump type to apply to version.txt (major, minor, or patch)' | |
| required: false | |
| type: choice | |
| options: | |
| - minor | |
| - patch | |
| - major | |
| default: minor | |
| use_existing_version: | |
| description: 'Use version as-is (no bump, no auto-commit)' | |
| required: false | |
| type: boolean | |
| default: false | |
| prerelease: | |
| description: 'Set as a pre-release' | |
| required: false | |
| type: boolean | |
| default: false | |
| run_performance_test: | |
| description: 'Run performance tests after release' | |
| required: false | |
| type: boolean | |
| default: true | |
| # Add permissions to allow pushing tags and packages | |
| permissions: | |
| contents: write | |
| packages: write | |
| env: | |
| GOFLAGS: "-mod=readonly" | |
| PRODUCT_NAME: "ThunderID" | |
| PRODUCT_NAME_LOWER: "thunderid" | |
| RELEASE_BRANCH: "release" | |
| RELEASE_GIT_USER_NAME: "thunder-automation-bot" | |
| RELEASE_GIT_USER_EMAIL: "thunder-bot@wso2.com" | |
| jobs: | |
| build: | |
| name: ⚡ Build | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.get_version.outputs.version }} | |
| prerelease: ${{ steps.get_version.outputs.prerelease }} | |
| run_performance_test: ${{ steps.get_version.outputs.run_performance_test }} | |
| use_existing_version: ${{ steps.get_version.outputs.use_existing_version }} | |
| steps: | |
| - name: 📥 Checkout Code | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.THUNDER_AUTOMATION_BOT }} | |
| ref: ${{ env.RELEASE_BRANCH }} | |
| - name: 📝 Determine Release Version | |
| id: get_version | |
| run: | | |
| # Read current version from version.txt | |
| if [ ! -f version.txt ] || [ -z "$(cat version.txt | tr -d '[:space:]')" ]; then | |
| echo "❌ Error: version.txt not found or empty" | |
| exit 1 | |
| fi | |
| CURRENT_VERSION=$(tr -d '[:space:]' < version.txt) | |
| # Strip leading 'v' for semver parsing | |
| SEMVER="${CURRENT_VERSION#v}" | |
| if [[ $SEMVER =~ ^([0-9]+)\.([0-9]+)\.([0-9]+) ]]; then | |
| CUR_MAJOR="${BASH_REMATCH[1]}" | |
| CUR_MINOR="${BASH_REMATCH[2]}" | |
| CUR_PATCH="${BASH_REMATCH[3]}" | |
| else | |
| echo "❌ Error: Could not parse version '$CURRENT_VERSION' from version.txt" | |
| exit 1 | |
| fi | |
| if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then | |
| PRERELEASE="${{ github.event.inputs.prerelease }}" | |
| RUN_PERF_TEST="${{ github.event.inputs.run_performance_test }}" | |
| BUMP_TYPE="${{ github.event.inputs.bump_type }}" | |
| USE_EXISTING_VERSION="${{ github.event.inputs.use_existing_version }}" | |
| else | |
| # Scheduled run — default to minor bump | |
| PRERELEASE="false" | |
| RUN_PERF_TEST="true" | |
| BUMP_TYPE="minor" | |
| USE_EXISTING_VERSION="false" | |
| fi | |
| if [ "$USE_EXISTING_VERSION" == "true" ]; then | |
| VERSION="$CURRENT_VERSION" | |
| echo "✅ Using existing version from version.txt: $VERSION" | |
| else | |
| case "$BUMP_TYPE" in | |
| major) | |
| VERSION="v$((CUR_MAJOR + 1)).0.0" | |
| ;; | |
| minor) | |
| VERSION="v${CUR_MAJOR}.$((CUR_MINOR + 1)).0" | |
| ;; | |
| patch) | |
| VERSION="v${CUR_MAJOR}.${CUR_MINOR}.$((CUR_PATCH + 1))" | |
| ;; | |
| *) | |
| echo "❌ Error: Invalid bump_type '$BUMP_TYPE'. Must be major, minor, or patch." | |
| exit 1 | |
| ;; | |
| esac | |
| fi | |
| echo "✅ Selected release version: $VERSION (use_existing_version: $USE_EXISTING_VERSION, bump: $BUMP_TYPE, Prerelease: $PRERELEASE, Perf Test: $RUN_PERF_TEST)" | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "prerelease=$PRERELEASE" >> $GITHUB_OUTPUT | |
| echo "run_performance_test=$RUN_PERF_TEST" >> $GITHUB_OUTPUT | |
| echo "use_existing_version=$USE_EXISTING_VERSION" >> $GITHUB_OUTPUT | |
| - name: ✅ Validate Release Version | |
| run: | | |
| VERSION="${{ steps.get_version.outputs.version }}" | |
| # Check version format | |
| if ! [[ $VERSION =~ ^v[0-9]+\.[0-9]+(\.[0-9]+)?(-[0-9a-zA-Z.-]+)?(\+[0-9a-zA-Z.-]+)?$ ]]; then | |
| echo "❌ Error: Version '$VERSION' does not follow format vX.Y[.Z][-PRERELEASE][+BUILD]" | |
| echo "❌ Version must start with 'v'" | |
| exit 1 | |
| fi | |
| echo "✅ Version '$VERSION' format is valid" | |
| # Check if tag already exists | |
| if git rev-parse "$VERSION" >/dev/null 2>&1; then | |
| echo "❌ Error: Version '$VERSION' already exists as a git tag" | |
| echo "❌ Please update version.txt with a new version before running the release" | |
| exit 1 | |
| fi | |
| echo "✅ Version '$VERSION' does not exist yet - proceeding with release" | |
| - name: 🏷️ Update Product Version | |
| if: ${{ steps.get_version.outputs.use_existing_version != 'true' }} | |
| run: | | |
| VERSION="${{ steps.get_version.outputs.version }}" | |
| echo "$VERSION" > version.txt | |
| echo "✅ Updated version.txt to $VERSION" | |
| - name: 📝 Update README Version References | |
| if: ${{ steps.get_version.outputs.use_existing_version != 'true' }} | |
| run: | | |
| VERSION="${{ steps.get_version.outputs.version }}" | |
| echo "📝 Updating README.md docker-compose curl URL to $VERSION" | |
| # Update the docker-compose.yml curl URL in README.md | |
| sed -i -E "s|(https://raw\.githubusercontent\.com/asgardeo/thunder/)v[0-9]+\.[0-9]+\.[0-9]+(/.+docker-compose\.yml)|\1${VERSION}\2|g" README.md | |
| echo "✅ Updated README.md curl URL to $VERSION" | |
| grep 'docker-compose.yml' README.md | |
| - name: 📝 Update Helm and Sample App Versions | |
| if: ${{ steps.get_version.outputs.use_existing_version != 'true' }} | |
| run: | | |
| VERSION="${{ steps.get_version.outputs.version }}" | |
| SEMVER_VERSION="${VERSION#v}" | |
| echo "📝 Updating install/helm/Chart.yaml to $SEMVER_VERSION" | |
| sed -i -E "s/^version: .*/version: ${SEMVER_VERSION}/" install/helm/Chart.yaml | |
| sed -i -E "s/^appVersion: .*/appVersion: \"${SEMVER_VERSION}\"/" install/helm/Chart.yaml | |
| echo "📝 Updating OpenChoreo Helm chart versions to $SEMVER_VERSION" | |
| sed -i -E "s/^version: .*/version: ${SEMVER_VERSION}/" install/openchoreo/helm/Chart.yaml | |
| sed -i -E "s/^appVersion: .*/appVersion: \"${SEMVER_VERSION}\"/" install/openchoreo/helm/Chart.yaml | |
| sed -i -E "s/^version: .*/version: ${SEMVER_VERSION}/" install/openchoreo/helm/charts/${PRODUCT_NAME_LOWER}-oc-componenttype/Chart.yaml | |
| sed -i -E "s/^version: .*/version: ${SEMVER_VERSION}/" install/openchoreo/helm/charts/${PRODUCT_NAME_LOWER}-component/Chart.yaml | |
| # Update sub-chart dependency versions in the umbrella chart (indented version: entries) | |
| sed -i -E "s/(^[[:space:]]+version: \")[^\"]*/\1${SEMVER_VERSION}/" install/openchoreo/helm/Chart.yaml | |
| echo "📝 Updating sample app package versions to $SEMVER_VERSION" | |
| cd samples/apps/react-api-based-sample | |
| npm version "$SEMVER_VERSION" --no-git-tag-version --allow-same-version | |
| cd "$GITHUB_WORKSPACE/samples/apps/react-sdk-sample" | |
| npm version "$SEMVER_VERSION" --no-git-tag-version --allow-same-version | |
| cd "$GITHUB_WORKSPACE/samples/apps/react-vanilla-sample" | |
| npm version "$SEMVER_VERSION" --no-git-tag-version --allow-same-version | |
| cd server | |
| npm version "$SEMVER_VERSION" --no-git-tag-version --allow-same-version | |
| cd "$GITHUB_WORKSPACE" | |
| echo "✅ Updated Helm chart and sample app versions to $SEMVER_VERSION" | |
| - name: 📤 Commit and Push Version Bump | |
| if: ${{ steps.get_version.outputs.use_existing_version != 'true' }} | |
| run: | | |
| VERSION="${{ steps.get_version.outputs.version }}" | |
| git config --local user.name "${{ env.RELEASE_GIT_USER_NAME }}" | |
| git config --local user.email "${{ env.RELEASE_GIT_USER_EMAIL }}" | |
| git add \ | |
| version.txt \ | |
| README.md \ | |
| install/helm/Chart.yaml \ | |
| install/openchoreo/helm/Chart.yaml \ | |
| install/openchoreo/helm/charts/${PRODUCT_NAME_LOWER}-oc-componenttype/Chart.yaml \ | |
| install/openchoreo/helm/charts/${PRODUCT_NAME_LOWER}-component/Chart.yaml \ | |
| samples/apps/react-api-based-sample/package-lock.json \ | |
| samples/apps/react-api-based-sample/package.json \ | |
| samples/apps/react-sdk-sample/package-lock.json \ | |
| samples/apps/react-sdk-sample/package.json \ | |
| samples/apps/react-vanilla-sample/package-lock.json \ | |
| samples/apps/react-vanilla-sample/package.json \ | |
| samples/apps/react-vanilla-sample/server/package-lock.json \ | |
| samples/apps/react-vanilla-sample/server/package.json | |
| if git diff --cached --quiet; then | |
| echo "✅ No changes to commit (files already at $VERSION)" | |
| else | |
| git commit -m "[Release] Bump version to ${VERSION}" | |
| git push origin HEAD:release | |
| echo "✅ Pushed version bump commit to release branch" | |
| fi | |
| - name: ⚙️ Set up Go Environment | |
| uses: ./.github/actions/setup-go | |
| - name: 🗄️ Cache Go Modules | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 | |
| id: cache-go-modules | |
| with: | |
| path: | | |
| ~/.cache/go-build | |
| ~/go/pkg/mod | |
| key: ${{ runner.os }}-go-modules-${{ hashFiles('**/go.sum') }} | |
| restore-keys: | | |
| ${{ runner.os }}-go-modules- | |
| - name: 📦 Install Dependencies | |
| run: | | |
| cd backend | |
| go mod download | |
| cd ../tests/integration | |
| go mod download | |
| - name: 🧹 Clean Previous Builds | |
| run: make clean | |
| - name: 🔨 Build Product with Coverage | |
| run: | | |
| set -e | |
| make build_with_coverage_only OS=$(go env GOOS) ARCH=$(go env GOARCH) | |
| # Find the built distribution | |
| DIST_PATH=$(find target/dist -name "$PRODUCT_NAME_LOWER-*.zip" | head -1) | |
| echo "Built distribution: $DIST_PATH" | |
| - name: 📦 Upload Built Distribution | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: product-distribution | |
| path: target/dist/*.zip | |
| if-no-files-found: error | |
| test-integration: | |
| name: 🧪 Integration Tests (${{ matrix.database }}) | |
| needs: build | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| database: [sqlite, postgres] | |
| fail-fast: false | |
| services: | |
| postgres: | |
| image: postgres:latest | |
| env: | |
| POSTGRES_USER: dbuser | |
| POSTGRES_PASSWORD: dbpassword | |
| POSTGRES_DB: thunderdb | |
| ports: | |
| - 5432:5432 | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| steps: | |
| - name: 📥 Checkout Code | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| with: | |
| ref: ${{ env.RELEASE_BRANCH }} | |
| - name: ⚙️ Set up Go Environment | |
| uses: ./.github/actions/setup-go | |
| - name: 🗄️ Cache Go Modules | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 | |
| id: cache-go-modules | |
| with: | |
| path: | | |
| ~/.cache/go-build | |
| ~/go/pkg/mod | |
| key: ${{ runner.os }}-go-modules-${{ hashFiles('**/go.sum') }} | |
| restore-keys: | | |
| ${{ runner.os }}-go-modules- | |
| - name: 📦 Install Dependencies | |
| run: | | |
| cd backend | |
| go mod download | |
| cd ../tests/integration | |
| go mod download | |
| - name: 📝 Configure Test Database | |
| run: | | |
| chmod +x tests/integration/resources/scripts/setup-test-config.sh | |
| ./tests/integration/resources/scripts/setup-test-config.sh | |
| env: | |
| DB_TYPE: ${{ matrix.database }} | |
| - name: 🧪 Run Integration Tests (${{ matrix.database }}) | |
| uses: ./.github/actions/run-integration-tests | |
| with: | |
| database-type: ${{ matrix.database }} | |
| coverage-enabled: true | |
| validate-windows: | |
| name: 🪟 Validate Windows PowerShell | |
| needs: build | |
| uses: ./.github/workflows/windows-powershell-validation.yml | |
| build-and-package: | |
| name: 📦 Build and Package Release | |
| runs-on: ubuntu-latest | |
| needs: [build, test-integration, validate-windows] | |
| steps: | |
| - name: 📥 Checkout Code | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| with: | |
| fetch-depth: 0 | |
| ref: ${{ env.RELEASE_BRANCH }} | |
| - name: 🏷️ Update Product Version | |
| run: | | |
| VERSION="${{ needs.build-product.outputs.version }}" | |
| echo "$VERSION" > version.txt | |
| - name: ⚙️ Set up Go Environment | |
| uses: ./.github/actions/setup-go | |
| - name: 🗄️ Cache Go Modules | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 | |
| id: cache-go-modules | |
| with: | |
| path: | | |
| ~/.cache/go-build | |
| ~/go/pkg/mod | |
| key: ${{ runner.os }}-go-modules-${{ hashFiles('**/go.sum') }} | |
| restore-keys: | | |
| ${{ runner.os }}-go-modules- | |
| - name: 📦 Install Dependencies | |
| run: | | |
| cd backend | |
| go mod download | |
| cd ../tests/integration | |
| go mod download | |
| - name: 🔐 Generate and Upload Certificates | |
| uses: ./.github/actions/generate-certificates | |
| with: | |
| show-cert-info: 'true' | |
| product-name: ${{ env.PRODUCT_NAME }} | |
| - name: 🔨 Build Release Artifacts | |
| uses: ./.github/actions/build-multiplatform | |
| - name: 📝 Read Updated Version | |
| id: version | |
| run: echo "version=$(cat version.txt)" >> $GITHUB_OUTPUT | |
| - name: 📦 Upload Backend Distribution Artifacts | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: product-distribution | |
| path: target/dist/*.zip | |
| if-no-files-found: error | |
| overwrite: true | |
| - name: 🏷️ Create Git Tag | |
| run: | | |
| git config --local user.email "action@github.com" | |
| git config --local user.name "GitHub Action" | |
| TAG_VERSION="${{ needs.build-product.outputs.version }}" | |
| if [[ ! $TAG_VERSION == v* ]]; then | |
| TAG_VERSION="v$TAG_VERSION" | |
| fi | |
| git tag -a "$TAG_VERSION" -m "Release $TAG_VERSION" | |
| git push origin "$TAG_VERSION" | |
| - name: 🐳 Set up Docker Buildx | |
| uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 | |
| - name: 🔐 Log in to GitHub Container Registry | |
| uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: 📥 Download Shared Certificates for Docker | |
| uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 | |
| with: | |
| name: ssl-certificates | |
| path: target/out/.cert/ | |
| - name: 📋 Prepare Docker Build Context | |
| run: | | |
| # Copy certificates into the Docker build context | |
| mkdir -p docker-certs | |
| cp target/out/.cert/server.cert docker-certs/ | |
| cp target/out/.cert/server.key docker-certs/ | |
| echo "✅ Certificates prepared for Docker build context" | |
| - name: 🐳 Build and Push Multi-Arch Docker Image | |
| run: | | |
| # Convert repository name to lowercase for GHCR | |
| REPO_NAME=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]') | |
| IMAGE_NAME="ghcr.io/${REPO_NAME}" | |
| # Get version without 'v' prefix for Docker tags | |
| DOCKER_VERSION="${{ needs.build-product.outputs.version }}" | |
| if [[ $DOCKER_VERSION == v* ]]; then | |
| DOCKER_VERSION="${DOCKER_VERSION#v}" | |
| fi | |
| echo "🐳 Building and pushing Docker image: ${IMAGE_NAME}:${DOCKER_VERSION}" | |
| # Build and push multi-arch image with version and latest tags | |
| # Pass shared certificates as build context with paths relative to build context | |
| docker buildx build \ | |
| --platform linux/amd64,linux/arm64 \ | |
| --tag "${IMAGE_NAME}:${DOCKER_VERSION}" \ | |
| --tag "${IMAGE_NAME}:latest" \ | |
| --build-arg CERT_FILE=docker-certs/server.cert \ | |
| --build-arg KEY_FILE=docker-certs/server.key \ | |
| --push \ | |
| . | |
| echo "✅ Docker image pushed successfully!" | |
| echo "📦 Image available at: ${IMAGE_NAME}:${DOCKER_VERSION}" | |
| echo "📦 Image available at: ${IMAGE_NAME}:latest" | |
| - name: 🏷️ Update Helm Values Image Tag | |
| run: | | |
| # Get version without 'v' prefix | |
| CHART_VERSION="${{ needs.build-product.outputs.version }}" | |
| if [[ $CHART_VERSION == v* ]]; then | |
| CHART_VERSION="${CHART_VERSION#v}" | |
| fi | |
| echo "📝 Updating Helm values.yaml with image tag ${CHART_VERSION}" | |
| # Check if the file exists and has the expected pattern | |
| if ! grep -q "tag: \"" install/helm/values.yaml; then | |
| echo "❌ Error: Could not find 'tag: \"' pattern in install/helm/values.yaml" | |
| echo "File may have been modified or corrupted" | |
| exit 1 | |
| fi | |
| # Update values.yaml with the new image tag | |
| sed -i "s/tag: \"[^\"]*\"/tag: \"${CHART_VERSION}\"/" install/helm/values.yaml | |
| echo "📝 Updating OpenChoreo Helm values with image tag ${CHART_VERSION}" | |
| sed -i "s/tag: \"[^\"]*\"/tag: \"${CHART_VERSION}\"/" install/openchoreo/helm/values.yaml | |
| sed -i "s/tag: \"[^\"]*\"/tag: \"${CHART_VERSION}\"/" install/openchoreo/helm/charts/${PRODUCT_NAME_LOWER}-component/values.yaml | |
| # Verify the replacement was successful | |
| if ! grep -q "tag: \"${CHART_VERSION}\"" install/helm/values.yaml; then | |
| echo "❌ Error: Failed to update image tag in values.yaml" | |
| echo "Expected to find: tag: \"${CHART_VERSION}\"" | |
| echo "Current content:" | |
| grep "tag:" install/helm/values.yaml | |
| exit 1 | |
| fi | |
| echo "✅ Successfully updated values.yaml with image tag: ${CHART_VERSION}" | |
| echo "✅ Verification passed - new tag is present in file" | |
| grep "tag:" install/helm/values.yaml | head -1 | |
| - name: ⚙️ Set up Helm | |
| uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 # v3 | |
| with: | |
| version: 'v3.12.3' | |
| - name: 📦 Package and Push Helm Chart to GHCR | |
| run: | | |
| CHART_NAME="$PRODUCT_NAME_LOWER" | |
| OWNER_NAME=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]') | |
| HELM_REGISTRY="ghcr.io/${OWNER_NAME}" | |
| # Get version without 'v' prefix for Helm chart version | |
| CHART_VERSION="${{ needs.build-product.outputs.version }}" | |
| if [[ $CHART_VERSION == v* ]]; then | |
| CHART_VERSION="${CHART_VERSION#v}" | |
| fi | |
| echo "📦 Packaging Helm chart: ${CHART_NAME} version ${CHART_VERSION}" | |
| # Ensure target directory exists | |
| mkdir -p target/dist/ | |
| # Package the Helm chart | |
| helm package install/helm --version "${CHART_VERSION}" --app-version "${CHART_VERSION}" --destination target/dist/ | |
| # Validate package was created | |
| if [ ! -f "target/dist/${CHART_NAME}-${CHART_VERSION}.tgz" ]; then | |
| echo "❌ Error: Helm chart package not found" | |
| exit 1 | |
| fi | |
| # Authenticate Helm to GHCR | |
| echo "${{ secrets.GITHUB_TOKEN }}" | helm registry login ghcr.io -u ${{ github.actor }} --password-stdin | |
| # Push the Helm chart to GHCR | |
| helm push "target/dist/${CHART_NAME}-${CHART_VERSION}.tgz" "oci://${HELM_REGISTRY}/helm-charts" | |
| echo "✅ Helm chart pushed successfully!" | |
| echo "📦 Helm chart available at: oci://${HELM_REGISTRY}/helm-charts" | |
| - name: 📦 Package and Push OpenChoreo Helm Charts to GHCR | |
| run: | | |
| OWNER_NAME=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]') | |
| HELM_REGISTRY="ghcr.io/${OWNER_NAME}/helm-charts" | |
| CHART_VERSION="${{ needs.build-product.outputs.version }}" | |
| if [[ $CHART_VERSION == v* ]]; then | |
| CHART_VERSION="${CHART_VERSION#v}" | |
| fi | |
| mkdir -p target/dist/openchoreo | |
| # Authenticate Helm to GHCR | |
| echo "${{ secrets.GITHUB_TOKEN }}" | helm registry login ghcr.io -u ${{ github.actor }} --password-stdin | |
| # Package and push oc-componenttype | |
| echo "📦 Packaging ${PRODUCT_NAME_LOWER}-oc-componenttype ${CHART_VERSION}" | |
| helm package install/openchoreo/helm/charts/${PRODUCT_NAME_LOWER}-oc-componenttype \ | |
| --version "${CHART_VERSION}" --app-version "${CHART_VERSION}" \ | |
| --destination target/dist/openchoreo/ | |
| helm push "target/dist/openchoreo/${PRODUCT_NAME_LOWER}-oc-componenttype-${CHART_VERSION}.tgz" "oci://${HELM_REGISTRY}" | |
| echo "✅ ${PRODUCT_NAME_LOWER}-oc-componenttype pushed to oci://${HELM_REGISTRY}" | |
| - name: 📝 Calculate Next Version | |
| id: next_version | |
| run: | | |
| # Get the current release version and remove 'v' prefix | |
| RELEASE_VERSION="${{ needs.build-product.outputs.version }}" | |
| if [[ $RELEASE_VERSION == v* ]]; then | |
| RELEASE_VERSION="${RELEASE_VERSION#v}" | |
| fi | |
| # Parse version components (handle both X.Y and X.Y.Z formats) | |
| if [[ $RELEASE_VERSION =~ ^([0-9]+)\.([0-9]+)\.([0-9]+) ]]; then | |
| # X.Y.Z format | |
| MAJOR="${BASH_REMATCH[1]}" | |
| MINOR="${BASH_REMATCH[2]}" | |
| PATCH="${BASH_REMATCH[3]}" | |
| elif [[ $RELEASE_VERSION =~ ^([0-9]+)\.([0-9]+) ]]; then | |
| # X.Y format | |
| MAJOR="${BASH_REMATCH[1]}" | |
| MINOR="${BASH_REMATCH[2]}" | |
| PATCH="0" | |
| else | |
| echo "❌ Error: Unable to parse version format: $RELEASE_VERSION" | |
| exit 1 | |
| fi | |
| # Bump minor version for next development cycle | |
| NEXT_MINOR=$((MINOR + 1)) | |
| NEXT_VERSION="${MAJOR}.${NEXT_MINOR}.0" | |
| echo "✅ Next development version: $NEXT_VERSION" | |
| echo "next_version=$NEXT_VERSION" >> $GITHUB_OUTPUT | |
| - name: 🏷️ Update Product Version | |
| run: | | |
| NEXT_VERSION="v${{ steps.next_version.outputs.next_version }}" | |
| echo "$NEXT_VERSION" > version.txt | |
| echo "✅ Updated version.txt to $NEXT_VERSION" | |
| - name: ⚙️ Set up Node.js for Version Update | |
| uses: ./.github/actions/setup-node | |
| with: | |
| node-version: 'lts/*' | |
| package-manager: 'npm' | |
| dependency-path: 'samples/apps/react-vanilla-sample' | |
| - name: 📦 Install pnpm | |
| uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 | |
| with: | |
| version: 9 | |
| - name: 🏷️ Update Sample Apps Version | |
| run: | | |
| NEXT_VERSION="${{ steps.next_version.outputs.next_version }}" | |
| echo "📝 Setting sample apps version to $NEXT_VERSION" | |
| # Update the react-vanilla sample app package.json | |
| cd samples/apps/react-vanilla-sample | |
| npm version $NEXT_VERSION --no-git-tag-version --allow-same-version | |
| # Update the server package.json | |
| cd server | |
| npm version $NEXT_VERSION --no-git-tag-version --allow-same-version | |
| cd "$GITHUB_WORKSPACE" | |
| # Update the react-sdk sample app package.json | |
| cd samples/apps/react-sdk-sample | |
| pnpm version $NEXT_VERSION --no-git-tag-version --allow-same-version | |
| cd "$GITHUB_WORKSPACE" | |
| # Update the react-api-based sample app package.json | |
| cd samples/apps/react-api-based-sample | |
| pnpm version $NEXT_VERSION --no-git-tag-version --allow-same-version | |
| cd "$GITHUB_WORKSPACE" | |
| echo "✅ Updated sample apps version to $NEXT_VERSION" | |
| package-samples-linux: | |
| name: 📦 Package Linux & Windows Samples | |
| runs-on: ubuntu-latest | |
| needs: [build, build-and-package] | |
| steps: | |
| - name: 📥 Checkout Code | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| with: | |
| fetch-depth: 0 | |
| ref: ${{ env.RELEASE_BRANCH }} | |
| - name: ⚙️ Setup Samples Environment | |
| uses: ./.github/actions/setup-samples-environment | |
| - name: 📝 Update Sample Apps Version | |
| uses: ./.github/actions/update-sample-versions | |
| with: | |
| version: ${{ needs.build-product.outputs.version }} | |
| - name: 📦 Build and Package Linux Samples | |
| run: | | |
| ./scripts/package-samples.sh linux x64 | |
| ./scripts/package-samples.sh linux arm64 | |
| - name: 📦 Build and Package Windows Samples | |
| run: ./scripts/package-samples.sh win x64 | |
| - name: 📦 Upload Linux & Windows Sample Artifacts | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: ${{ env.PRODUCT_NAME_LOWER }}-samples-linux-windows | |
| path: target/dist/*.zip | |
| if-no-files-found: error | |
| package-samples-macos: | |
| name: 📦 Package macOS Samples | |
| runs-on: macos-latest | |
| needs: [build, build-and-package] | |
| steps: | |
| - name: 📥 Checkout Code | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| with: | |
| fetch-depth: 0 | |
| ref: ${{ env.RELEASE_BRANCH }} | |
| - name: ⚙️ Setup Samples Environment | |
| uses: ./.github/actions/setup-samples-environment | |
| - name: 📝 Update Sample Apps Version | |
| uses: ./.github/actions/update-sample-versions | |
| with: | |
| version: ${{ needs.build-product.outputs.version }} | |
| - name: 📦 Build and Package macOS Samples | |
| run: | | |
| ./scripts/package-samples.sh macos x64 | |
| ./scripts/package-samples.sh macos arm64 | |
| - name: 📦 Upload macOS Sample Artifacts | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: ${{ env.PRODUCT_NAME_LOWER }}-samples-macos | |
| path: target/dist/*.zip | |
| if-no-files-found: error | |
| release: | |
| name: 🚀 Release | |
| runs-on: ubuntu-latest | |
| needs: [build, build-and-package, package-samples-linux, package-samples-macos] | |
| outputs: | |
| release_tag: ${{ steps.release_info.outputs.release_tag }} | |
| steps: | |
| - name: 📥 Checkout Code | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| with: | |
| fetch-depth: 0 | |
| ref: ${{ env.RELEASE_BRANCH }} | |
| - name: 📥 Download Backend Artifacts | |
| uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 | |
| with: | |
| name: product-distribution | |
| path: ./backend-artifacts | |
| - name: 📥 Download Linux & Windows Sample Artifacts | |
| uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 | |
| with: | |
| name: ${{ env.PRODUCT_NAME_LOWER }}-samples-linux-windows | |
| path: ./linux-windows-artifacts | |
| - name: 📥 Download macOS Sample Artifacts | |
| uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 | |
| with: | |
| name: ${{ env.PRODUCT_NAME_LOWER }}-samples-macos | |
| path: ./macos-artifacts | |
| - name: 📦 Combine All Distribution Artifacts | |
| run: | | |
| mkdir -p target/dist | |
| # Copy backend artifacts | |
| cp ./backend-artifacts/*.zip target/dist/ || true | |
| # Copy sample artifacts from each platform | |
| cp ./linux-windows-artifacts/*.zip target/dist/ || true | |
| cp ./macos-artifacts/*.zip target/dist/ || true | |
| echo "✅ Combined all artifacts:" | |
| ls -la target/dist/ | |
| - name: 📦 Upload Final Combined Artifacts | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: final-distribution | |
| path: target/dist/*.zip | |
| if-no-files-found: error | |
| - name: 📝 Read Version | |
| id: version | |
| run: | | |
| VERSION="${{ needs.build-product.outputs.version }}" | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| - name: 📝 Generate Automatic Release Notes | |
| id: generate_notes | |
| uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 | |
| with: | |
| script: | | |
| const currentTag = '${{ needs.build-product.outputs.version }}'; | |
| try { | |
| // Get only the 2 most recent releases (current + previous) | |
| const { data: releases } = await github.rest.repos.listReleases({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| per_page: 2 | |
| }); | |
| console.log(`Found ${releases.length} recent release(s)`); | |
| // Find the previous release (skip the current one if it exists) | |
| let previousTag = null; | |
| if (releases.length === 0) { | |
| console.log('No previous releases found - this is the first release'); | |
| } else if (releases.length === 1) { | |
| // Only one release exists | |
| if (releases[0].tag_name === currentTag) { | |
| console.log('Current release found, but no previous release exists'); | |
| } else { | |
| previousTag = releases[0].tag_name; | |
| console.log(`Previous release tag: ${previousTag}`); | |
| } | |
| } else { | |
| // Two or more releases exist | |
| if (releases[0].tag_name === currentTag) { | |
| // Current release is the most recent, use the second one | |
| previousTag = releases[1].tag_name; | |
| console.log(`Current release found at position 0, using position 1: ${previousTag}`); | |
| } else { | |
| // Current release doesn't exist yet or is not the most recent | |
| previousTag = releases[0].tag_name; | |
| console.log(`Using most recent release: ${previousTag}`); | |
| } | |
| } | |
| if (previousTag !== null && previousTag !== undefined) { | |
| console.log(`Will compare ${previousTag}...${currentTag}`); | |
| } | |
| // Generate release notes | |
| // Build the request parameters conditionally | |
| const releaseNotesParams = { | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| tag_name: currentTag, | |
| }; | |
| // Only include previous_tag_name if it exists | |
| if (previousTag !== null && previousTag !== undefined) { | |
| releaseNotesParams.previous_tag_name = previousTag; | |
| } | |
| const { data } = await github.rest.repos.generateReleaseNotes(releaseNotesParams); | |
| // Only save to file if we have actual content | |
| const releaseNotesBody = data.body || ''; | |
| if (releaseNotesBody.trim().length > 0) { | |
| const fs = require('fs'); | |
| fs.writeFileSync('release-notes.md', releaseNotesBody); | |
| console.log('✅ Generated release notes successfully'); | |
| console.log(`Release notes length: ${releaseNotesBody.length} characters`); | |
| } else { | |
| console.log('⚠️ Generated release notes are empty, skipping file creation'); | |
| } | |
| return releaseNotesBody; | |
| } catch (error) { | |
| console.log('⚠️ Could not generate release notes:', error.message); | |
| // Return empty string if generation fails (e.g., for first release) | |
| return ''; | |
| } | |
| - name: 📝 Extract README Content for Release | |
| id: readme_extract | |
| run: | | |
| # Get the release version without v prefix for replacement | |
| RELEASE_VERSION="${{ needs.build-product.outputs.version }}" | |
| if [[ $RELEASE_VERSION == v* ]]; then | |
| RELEASE_VERSION="${RELEASE_VERSION#v}" | |
| fi | |
| # Extract introduction (everything before first --- divider) | |
| INTRO=$(awk 'BEGIN{flag=1} /^---$/{flag=0; exit} flag{print}' README.md) | |
| # Extract Quick Start section | |
| QUICKSTART=$(sed -n '/^## ⚡ Quickstart/,/^---$/p' README.md | head -n -1) | |
| # Extract license section including header | |
| LICENSE=$(grep -A 5 "^## License" README.md) | |
| # Replace <version> placeholders with actual version | |
| INTRO=$(echo "$INTRO" | sed "s/<version>/$RELEASE_VERSION/g") | |
| QUICKSTART=$(echo "$QUICKSTART" | sed "s/<version>/$RELEASE_VERSION/g") | |
| # Replace 'latest' placeholders with actual version for release notes | |
| INTRO=$(echo "$INTRO" | sed "s/:latest/:$RELEASE_VERSION/g") | |
| QUICKSTART=$(echo "$QUICKSTART" | sed "s/:latest/:$RELEASE_VERSION/g") | |
| INTRO=$(echo "$INTRO" | sed "s/latest release/$RELEASE_VERSION release/g") | |
| QUICKSTART=$(echo "$QUICKSTART" | sed "s/latest release/$RELEASE_VERSION release/g") | |
| # Handle other 'latest' references | |
| INTRO=$(echo "$INTRO" | sed "s/latest release of $PRODUCT_NAME/$RELEASE_VERSION release of $PRODUCT_NAME/g") | |
| QUICKSTART=$(echo "$QUICKSTART" | sed "s/latest release of $PRODUCT_NAME/$RELEASE_VERSION release of $PRODUCT_NAME/g") | |
| # Add direct download links for $PRODUCT_NAME server - replace download instruction and example paragraph | |
| # Create the $PRODUCT_NAME downloads table with proper newlines using printf | |
| PRODUCT_TABLE=$(printf "%s\n%s\n%s\n%s\n%s\n%s\n%s" \ | |
| " | OS | Architecture | Download Link |" \ | |
| " |-------|-------------|-------------|" \ | |
| " | macOS | ARM64 (Apple Silicon) | [${PRODUCT_NAME_LOWER}-${RELEASE_VERSION}-macos-arm64.zip](https://github.com/${{ github.repository }}/releases/download/v${RELEASE_VERSION}/${PRODUCT_NAME_LOWER}-${RELEASE_VERSION}-macos-arm64.zip) |" \ | |
| " | macOS | x64 (Intel) | [${PRODUCT_NAME_LOWER}-${RELEASE_VERSION}-macos-x64.zip](https://github.com/${{ github.repository }}/releases/download/v${RELEASE_VERSION}/${PRODUCT_NAME_LOWER}-${RELEASE_VERSION}-macos-x64.zip) |" \ | |
| " | Linux | x64 | [${PRODUCT_NAME_LOWER}-${RELEASE_VERSION}-linux-x64.zip](https://github.com/${{ github.repository }}/releases/download/v${RELEASE_VERSION}/${PRODUCT_NAME_LOWER}-${RELEASE_VERSION}-linux-x64.zip) |" \ | |
| " | Linux | ARM64 | [${PRODUCT_NAME_LOWER}-${RELEASE_VERSION}-linux-arm64.zip](https://github.com/${{ github.repository }}/releases/download/v${RELEASE_VERSION}/${PRODUCT_NAME_LOWER}-${RELEASE_VERSION}-linux-arm64.zip) |" \ | |
| " | Windows | x64 | [${PRODUCT_NAME_LOWER}-${RELEASE_VERSION}-win-x64.zip](https://github.com/${{ github.repository }}/releases/download/v${RELEASE_VERSION}/${PRODUCT_NAME_LOWER}-${RELEASE_VERSION}-win-x64.zip) |") | |
| # Replace the download instruction with the table using awk for proper handling | |
| QUICKSTART=$(echo "$QUICKSTART" | awk -v table="$PRODUCT_TABLE" ' | |
| /Download `'"${PRODUCT_NAME_LOWER}"'-.*-<os>-<arch>\.zip` from the \[.*release\]/ { | |
| print table | |
| next | |
| } | |
| { print } | |
| ') | |
| # Remove the example paragraph that follows (it's now redundant with the table) | |
| QUICKSTART=$(echo "$QUICKSTART" | sed '/For example, if you are using a MacOS machine with a Apple Silicon (ARM64) processor, you would download `'"${PRODUCT_NAME_LOWER}-${RELEASE_VERSION}"'-macos-arm64\.zip`\./d') | |
| # Create the React Vanilla Sample App downloads table with proper newlines using printf | |
| VANILLA_SAMPLE_TABLE=$(printf "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s" \ | |
| " | OS | Architecture | Download Link |" \ | |
| " |-------|-------------|-------------|" \ | |
| " | macOS | ARM64 (Apple Silicon) | [sample-app-react-vanilla-${RELEASE_VERSION}-macos-arm64.zip](https://github.com/${{ github.repository }}/releases/download/v${RELEASE_VERSION}/sample-app-react-vanilla-${RELEASE_VERSION}-macos-arm64.zip) |" \ | |
| " | macOS | x64 (Intel) | [sample-app-react-vanilla-${RELEASE_VERSION}-macos-x64.zip](https://github.com/${{ github.repository }}/releases/download/v${RELEASE_VERSION}/sample-app-react-vanilla-${RELEASE_VERSION}-macos-x64.zip) |" \ | |
| " | Linux | x64 | [sample-app-react-vanilla-${RELEASE_VERSION}-linux-x64.zip](https://github.com/${{ github.repository }}/releases/download/v${RELEASE_VERSION}/sample-app-react-vanilla-${RELEASE_VERSION}-linux-x64.zip) |" \ | |
| " | Linux | ARM64 | [sample-app-react-vanilla-${RELEASE_VERSION}-linux-arm64.zip](https://github.com/${{ github.repository }}/releases/download/v${RELEASE_VERSION}/sample-app-react-vanilla-${RELEASE_VERSION}-linux-arm64.zip) |" \ | |
| " | Windows | x64 | [sample-app-react-vanilla-${RELEASE_VERSION}-win-x64.zip](https://github.com/${{ github.repository }}/releases/download/v${RELEASE_VERSION}/sample-app-react-vanilla-${RELEASE_VERSION}-win-x64.zip) |") | |
| # Create the React SDK Sample App downloads table with proper newlines using printf | |
| SDK_SAMPLE_TABLE=$(printf "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s" \ | |
| " | OS | Architecture | Download Link |" \ | |
| " |-------|-------------|-------------|" \ | |
| " | macOS | ARM64 (Apple Silicon) | [sample-app-react-sdk-${RELEASE_VERSION}-macos-arm64.zip](https://github.com/${{ github.repository }}/releases/download/v${RELEASE_VERSION}/sample-app-react-sdk-${RELEASE_VERSION}-macos-arm64.zip) |" \ | |
| " | macOS | x64 (Intel) | [sample-app-react-sdk-${RELEASE_VERSION}-macos-x64.zip](https://github.com/${{ github.repository }}/releases/download/v${RELEASE_VERSION}/sample-app-react-sdk-${RELEASE_VERSION}-macos-x64.zip) |" \ | |
| " | Linux | x64 | [sample-app-react-sdk-${RELEASE_VERSION}-linux-x64.zip](https://github.com/${{ github.repository }}/releases/download/v${RELEASE_VERSION}/sample-app-react-sdk-${RELEASE_VERSION}-linux-x64.zip) |" \ | |
| " | Linux | ARM64 | [sample-app-react-sdk-${RELEASE_VERSION}-linux-arm64.zip](https://github.com/${{ github.repository }}/releases/download/v${RELEASE_VERSION}/sample-app-react-sdk-${RELEASE_VERSION}-linux-arm64.zip) |" \ | |
| " | Windows | x64 | [sample-app-react-sdk-${RELEASE_VERSION}-win-x64.zip](https://github.com/${{ github.repository }}/releases/download/v${RELEASE_VERSION}/sample-app-react-sdk-${RELEASE_VERSION}-win-x64.zip) |") | |
| # Create the React API-based Sample App downloads table with proper newlines using printf | |
| API_SAMPLE_TABLE=$(printf "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s" \ | |
| " | OS | Architecture | Download Link |" \ | |
| " |-------|-------------|-------------|" \ | |
| " | macOS | ARM64 (Apple Silicon) | [sample-app-react-api-based-${RELEASE_VERSION}-macos-arm64.zip](https://github.com/${{ github.repository }}/releases/download/v${RELEASE_VERSION}/sample-app-react-api-based-${RELEASE_VERSION}-macos-arm64.zip) |" \ | |
| " | macOS | x64 (Intel) | [sample-app-react-api-based-${RELEASE_VERSION}-macos-x64.zip](https://github.com/${{ github.repository }}/releases/download/v${RELEASE_VERSION}/sample-app-react-api-based-${RELEASE_VERSION}-macos-x64.zip) |" \ | |
| " | Linux | x64 | [sample-app-react-api-based-${RELEASE_VERSION}-linux-x64.zip](https://github.com/${{ github.repository }}/releases/download/v${RELEASE_VERSION}/sample-app-react-api-based-${RELEASE_VERSION}-linux-x64.zip) |" \ | |
| " | Linux | ARM64 | [sample-app-react-api-based-${RELEASE_VERSION}-linux-arm64.zip](https://github.com/${{ github.repository }}/releases/download/v${RELEASE_VERSION}/sample-app-react-api-based-${RELEASE_VERSION}-linux-arm64.zip) |" \ | |
| " | Windows | x64 | [sample-app-react-api-based-${RELEASE_VERSION}-win-x64.zip](https://github.com/${{ github.repository }}/releases/download/v${RELEASE_VERSION}/sample-app-react-api-based-${RELEASE_VERSION}-win-x64.zip) |") | |
| # Replace the vanilla sample app download instruction with its table | |
| QUICKSTART=$(echo "$QUICKSTART" | awk -v table="$VANILLA_SAMPLE_TABLE" ' | |
| /Download `sample-app-react-vanilla-.*-<os>-<arch>\.zip` from the \[.*release\]/ { | |
| print table | |
| next | |
| } | |
| { print } | |
| ') | |
| # Replace the SDK sample app download instruction with its table | |
| QUICKSTART=$(echo "$QUICKSTART" | awk -v table="$SDK_SAMPLE_TABLE" ' | |
| /Download `sample-app-react-sdk-.*-<os>-<arch>\.zip` from the \[.*release\]/ { | |
| print table | |
| next | |
| } | |
| { print } | |
| ') | |
| # Replace the API-based sample app download instruction with its table | |
| QUICKSTART=$(echo "$QUICKSTART" | awk -v table="$API_SAMPLE_TABLE" ' | |
| /Download `sample-app-react-api-based-.*-<os>-<arch>\.zip` from the \[.*release\]/ { | |
| print table | |
| next | |
| } | |
| { print } | |
| ') | |
| # Read the generated release notes if they exist | |
| CHANGELOG="" | |
| if [ -f "release-notes.md" ]; then | |
| CHANGELOG=$(cat release-notes.md) | |
| echo "✅ Found generated release notes" | |
| else | |
| echo "⚠️ No release notes file found, skipping changelog" | |
| fi | |
| # Combine for release description with changelog | |
| echo "RELEASE_BODY<<EOF" >> $GITHUB_ENV | |
| echo "$INTRO" >> $GITHUB_ENV | |
| echo "" >> $GITHUB_ENV | |
| # Insert changelog | |
| if [ -n "$CHANGELOG" ]; then | |
| echo "$CHANGELOG" >> $GITHUB_ENV | |
| echo "" >> $GITHUB_ENV | |
| fi | |
| echo "$QUICKSTART" >> $GITHUB_ENV | |
| echo "" >> $GITHUB_ENV | |
| echo "$LICENSE" >> $GITHUB_ENV | |
| echo "EOF" >> $GITHUB_ENV | |
| - name: 📦 Create GitHub Release | |
| id: create_release | |
| uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2 | |
| with: | |
| tag_name: ${{ steps.version.outputs.version }} | |
| name: ${{ env.PRODUCT_NAME }} ${{ steps.version.outputs.version }} | |
| draft: false | |
| prerelease: ${{ needs.build-product.outputs.prerelease }} | |
| files: target/dist/*.zip | |
| body: ${{ env.RELEASE_BODY }} | |
| generate_release_notes: false | |
| - name: 🔔 Set Release Info | |
| id: release_info | |
| run: | | |
| RELEASE_VERSION="${{ steps.version.outputs.version }}" | |
| echo "release_name=${PRODUCT_NAME} ${RELEASE_VERSION}" >> $GITHUB_OUTPUT | |
| echo "release_tag=${RELEASE_VERSION}" >> $GITHUB_OUTPUT | |
| echo "release_url=https://github.com/${{ github.repository }}/releases/tag/${RELEASE_VERSION}" >> $GITHUB_OUTPUT | |
| - name: 🔔 Send Release Notification | |
| uses: ./.github/actions/release-notification | |
| with: | |
| webhook: ${{ secrets.GOOGLE_CHAT_WEBHOOK }} | |
| product-name: ${{ env.PRODUCT_NAME }} | |
| release-name: ${{ steps.release_info.outputs.release_name }} | |
| release-tag: ${{ steps.release_info.outputs.release_tag }} | |
| release-url: ${{ steps.release_info.outputs.release_url }} | |
| trigger-performance-test: | |
| name: 🧪 Trigger Performance Test | |
| runs-on: ubuntu-latest | |
| needs: [build, release] | |
| if: ${{ needs.build-product.outputs.run_performance_test == 'true' }} | |
| steps: | |
| - name: 📥 Checkout Code | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| with: | |
| ref: ${{ env.RELEASE_BRANCH }} | |
| - name: ⚡ Trigger Performance Test Workflows | |
| uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 | |
| with: | |
| github-token: ${{ secrets.THUNDER_GITHUB_BOT_TOKEN }} | |
| script: | | |
| // Construct the pack URL using the release version | |
| const releaseTag = '${{ needs.release.outputs.release_tag }}'; | |
| const productNameLower = process.env.PRODUCT_NAME_LOWER; | |
| const serverDistributionUrl = `https://github.com/${{ github.repository }}/releases/download/${releaseTag}/${productNameLower}-${releaseTag.replace('v', '')}-linux-x64.zip`; | |
| const pushBenchmarkToGitHub = ${{ github.repository == 'asgardeo/thunder' }}; | |
| try { | |
| console.log(`🔄 Triggering performance test workflow`); | |
| await github.rest.actions.createWorkflowDispatch({ | |
| owner: 'asgardeo', | |
| repo: 'thunder-performance', | |
| workflow_id: 'vm-perf-workflow.yml', | |
| ref: 'main', | |
| inputs: { | |
| THUNDER_PACK_URL: serverDistributionUrl, | |
| CONCURRENCY: '50,200,500', | |
| PUSH_BENCHMARKS_TO_GITHUB: pushBenchmarkToGitHub | |
| } | |
| }); | |
| console.log(`✅ Performance test workflow triggered successfully`); | |
| } catch (error) { | |
| console.error(`❌ Failed to trigger performance test workflow:`, error); | |
| } | |
| // Return success | |
| return {success: true}; | |
| trigger-deploy-docs: | |
| name: 📚 Trigger Deploy Documentation | |
| runs-on: ubuntu-latest | |
| needs: [build, release] | |
| steps: | |
| - name: 📚 Trigger Deploy Documentation Workflow | |
| uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 | |
| with: | |
| github-token: ${{ secrets.THUNDER_AUTOMATION_BOT }} | |
| script: | | |
| try { | |
| console.log('🔄 Triggering deploy-docs workflow...'); | |
| await github.rest.actions.createWorkflowDispatch({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| workflow_id: 'deploy-docs.yml', | |
| ref: 'main', | |
| inputs: { | |
| 'use-artifact': '' | |
| } | |
| }); | |
| console.log('✅ deploy-docs workflow triggered successfully'); | |
| } catch (error) { | |
| console.error('❌ Failed to trigger deploy-docs workflow:', error); | |
| core.setFailed(error.message); | |
| } |