Release 🚀 #30
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
| name: Release 🚀 | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| release_version: | |
| description: 'Version to release (e.g. 1.2.3)' | |
| required: true | |
| jobs: | |
| release: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| - name: Extract last released version | |
| run: | | |
| CURRENT_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) | |
| SNAP_BASE=$(echo "$CURRENT_VERSION" | sed 's/-SNAPSHOT//') | |
| echo "Last released version: $SNAP_BASE" | |
| echo "LAST_RELEASED_VERSION=$SNAP_BASE" >> $GITHUB_ENV | |
| - name: Setup Java | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: adopt | |
| java-version: 17 | |
| cache: maven | |
| server-id: vanillabp-central | |
| server-username: MAVEN_USERNAME | |
| server-password: MAVEN_PASSWORD | |
| gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} | |
| gpg-passphrase: GPG_PASSPHRASE | |
| - name: Configure npm authentication for npmjs.com | |
| run: | | |
| echo "//registry.npmjs.com/:_authToken=${{ secrets.NPM_PUBLISH_TOKEN }}" > ~/.npmrc | |
| echo "registry=https://registry.npmjs.com/" >> ~/.npmrc | |
| echo "always-auth=true" >> ~/.npmrc | |
| - name: Create release branch | |
| run: | | |
| git checkout -b release/${{ github.event.inputs.release_version }} origin/main | |
| - name: Set Maven release version | |
| run: | | |
| mvn versions:set -DnewVersion=${{ github.event.inputs.release_version }} | |
| find . -name pom.xml.versionsBackup -delete | |
| - name: Update npm package.json versions | |
| run: | | |
| find . -name package.json | while read file; do | |
| echo "🔧 Updating $file" | |
| tmp=$(mktemp) | |
| jq --arg v "${{ github.event.inputs.release_version }}" ' | |
| .version = $v | |
| | if .dependencies then | |
| .dependencies |= with_entries( | |
| if (.key | startswith("@vanillabp/")) | |
| then .value = $v else . end | |
| ) | |
| else . end | |
| | if .devDependencies then | |
| .devDependencies |= with_entries( | |
| if (.key | startswith("@vanillabp/")) | |
| then .value = $v else . end | |
| ) | |
| else . end | |
| | if .peerDependencies then | |
| .peerDependencies |= with_entries( | |
| if (.key | startswith("@vanillabp/")) | |
| then .value = $v else . end | |
| ) | |
| else . end | |
| ' "$file" > "$tmp" && mv "$tmp" "$file" | |
| done | |
| - name: Check for SNAPSHOT dependencies | |
| run: | | |
| SNAPSHOT_POMS=$(grep -R "<.*>.*SNAPSHOT<\/.*>" . --include=pom.xml || true) | |
| SNAPSHOT_PKGS=$(grep -R "\".*SNAPSHOT\"" . --include=package.json || true) | |
| if [ -n "$SNAPSHOT_POMS" ] || [ -n "$SNAPSHOT_PKGS" ]; then | |
| echo "::warning::Found SNAPSHOT dependencies in the project:" | |
| [ -n "$SNAPSHOT_POMS" ] && echo "$SNAPSHOT_POMS" | |
| [ -n "$SNAPSHOT_PKGS" ] && echo "$SNAPSHOT_PKGS" | |
| else | |
| echo "✅ No SNAPSHOT dependencies found." | |
| fi | |
| # Always exit successfully | |
| exit 0 | |
| - name: Hacky workaround to avoid npm DNS replication delay between publish and consume | |
| run: | | |
| IP=$(nslookup registry.npmjs.com | awk '/^Address: / { print $2; exit }') | |
| echo "$IP registry.npmjs.com" | sudo tee -a /etc/hosts | |
| - name: Build & deploy to Maven Central and npm | |
| run: | | |
| mvn --batch-mode -DskipTests -DskipITs \ | |
| -DaltDeploymentRepository=local::default::file:target/staging \ | |
| -Dnpm.registry=https://registry.npmjs.com \ | |
| -Dgpg.passphrase=$GPG_PASSPHRASE \ | |
| clean deploy -Prelease,central-portal,release-npm | |
| env: | |
| GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} | |
| MAVEN_USERNAME: ${{ secrets.MAVEN_CENTRAL_PORTAL_TOKEN_USER }} | |
| MAVEN_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PORTAL_TOKEN_PW }} | |
| - name: Commit release version | |
| run: | | |
| git config user.name "github-actions" | |
| git config user.email "[email protected]" | |
| git add -A | |
| git commit -m "Prepare release v${{ github.event.inputs.release_version }}" | |
| - name: Build runnable JARs | |
| run: | | |
| cd container && mvn --batch-mode -DskipTests -DskipITs -Dnpm.registry=https://registry.npmjs.com package spring-boot:repackage -Pskip-release-npm && cd .. | |
| cd development/simulator && mvn --batch-mode -DskipTests -DskipITs -Dnpm.registry=https://registry.npmjs.com package spring-boot:repackage -Pskip-release-npm && cd .. | |
| cd dev-shell-simulator && mvn --batch-mode -DskipTests -DskipITs -Dnpm.registry=https://registry.npmjs.com package spring-boot:repackage -Pskip-release-npm && cd ../.. | |
| - name: Create Git tag | |
| run: | | |
| git tag -a "${{ github.event.inputs.release_version }}" -m "Release ${{ github.event.inputs.release_version }}" | |
| git push origin --tags | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v1 | |
| with: | |
| tag_name: ${{ github.event.inputs.release_version }} | |
| name: v${{ github.event.inputs.release_version }} | |
| generate_release_notes: true | |
| append_body: | | |
| **Full Changelog:** [`${{ env.LAST_RELEASED_VERSION }}...${{ github.event.inputs.release_version }}`](https://github.com/vanillabp/business-cockpit/compare/${{ env.LAST_RELEASED_VERSION }}...${{ github.event.inputs.release_version }}) | |
| files: | | |
| **/*-runnable.jar | |
| draft: true | |
| - name: Calculate next snapshot version | |
| run: | | |
| RELEASE_VERSION=${{ github.event.inputs.release_version }} | |
| IFS='.' read -r major minor patch <<< "$RELEASE_VERSION" | |
| NEXT_PATCH=$((patch + 1)) | |
| echo "NEXT_SNAPSHOT=$major.$minor.${NEXT_PATCH}-SNAPSHOT" >> $GITHUB_ENV | |
| - name: Set next snapshot version | |
| run: | | |
| mvn versions:set -DnewVersion=${{ env.NEXT_SNAPSHOT }} | |
| find . -name pom.xml.versionsBackup -delete | |
| SNAP_BASE=$(echo "${{ env.NEXT_SNAPSHOT }}" | sed 's/-SNAPSHOT//') | |
| NEXT_PATCH=$(echo $SNAP_BASE | awk -F. '{$NF++; print}' OFS=.) | |
| # Update all package.json files using jq excluding node_modules | |
| find . -name node_modules -prune -o -name package.json -print | while read file; do | |
| echo "🔧 Updating $file" | |
| tmp=$(mktemp) | |
| jq --arg v "${{ env.NEXT_SNAPSHOT }}" \ | |
| --arg range ">=${{ env.NEXT_SNAPSHOT }} <${NEXT_PATCH}" ' | |
| .version = $v | |
| | if .dependencies then | |
| .dependencies |= with_entries( | |
| if (.key | startswith("@vanillabp/")) | |
| then .value = $range else . end | |
| ) | |
| else . end | |
| | if .devDependencies then | |
| .devDependencies |= with_entries( | |
| if (.key | startswith("@vanillabp/")) | |
| then .value = $range else . end | |
| ) | |
| else . end | |
| | if .peerDependencies then | |
| .peerDependencies |= with_entries( | |
| if (.key | startswith("@vanillabp/")) | |
| then .value = $range else . end | |
| ) | |
| else . end | |
| ' "$file" > "$tmp" && mv "$tmp" "$file" | |
| done | |
| - name: Configure npm authentication for GitHub Packages | |
| run: | | |
| echo "//npm.pkg.github.com/:_authToken=${{ secrets.GITHUB_TOKEN }}" > ~/.npmrc | |
| echo "@vanillabp:registry=https://npm.pkg.github.com/" >> ~/.npmrc | |
| echo "always-auth=true" >> ~/.npmrc | |
| - name: Build & publish new snapshot packages | |
| run: | | |
| mvn --batch-mode -s $GITHUB_WORKSPACE/.github/workflows/github-packages-settings.xml \ | |
| -Dnpm.prerelease=0 \ | |
| -Dnpm.registry=https://npm.pkg.github.com/ \ | |
| deploy | |
| env: | |
| USER_NAME: ${{ secrets.VANILLABP_USER_NAME }} | |
| USER_TOKEN: ${{ secrets.VANILLABP_USER_TOKEN }} | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Commit next snapshot version | |
| run: | | |
| git add -A | |
| git commit -m "Set next version ${{ env.NEXT_SNAPSHOT }}" | |
| git push origin HEAD:release/${{ github.event.inputs.release_version }} | |
| - name: Create PR to merge release branch into main | |
| run: | | |
| gh auth login --with-token <<< "${{ secrets.GITHUB_TOKEN }}" | |
| gh pr create \ | |
| --title "Merge release/${{ github.event.inputs.release_version }} into main" \ | |
| --body "Automated PR to merge release branch." \ | |
| --base main \ | |
| --head release/${{ github.event.inputs.release_version }} |