diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..6e166e90 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,259 @@ +# This workflow handles the complete release process for static-code-analysis +# It converts snapshot to release version, deploys to Maven Central via OSSRH, +# and then bumps to the next snapshot version + +name: Release to Maven Central +permissions: + contents: write + +on: + workflow_dispatch: + inputs: + release_version: + description: 'Release version (e.g., 0.18.0)' + required: true + type: string + next_snapshot_version: + description: 'Next snapshot version (e.g., 0.19.0-SNAPSHOT)' + required: true + type: string + +jobs: + release: + name: Release to Maven Central + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v6 + with: + token: ${{ secrets.GITHUB_TOKEN }} + fetch-depth: 0 + + - name: Set up JDK 11 + uses: actions/setup-java@v5 + with: + java-version: 11 + distribution: 'temurin' + cache: maven + server-id: ossrh + server-username: OSSRH_USERNAME + server-password: OSSRH_PASSWORD + gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} + gpg-passphrase: GPG_PASSPHRASE + + - name: Configure Git + run: | + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + + - name: Update version to release version + run: | + mvn versions:set -DnewVersion=${{ github.event.inputs.release_version }} + mvn versions:commit + + - name: Update parent POM versions in modules + run: | + # Update parent version in all child POMs + for pom in $(find . -name pom.xml -not -path "*/target/*" -not -path "*/src/test/resources/*"); do + if [ -f "$pom" ]; then + mvn versions:update-parent -DparentVersion=${{ github.event.inputs.release_version }} -f "$pom" + mvn versions:commit -f "$pom" + fi + done + + - name: Verify release version + run: | + echo "Updated version to:" + mvn help:evaluate -Dexpression=project.version -q -DforceStdout + + - name: Build without tests + run: mvn clean compile -DskipTests=true -DskipChecks=true + + - name: Deploy to Maven Central + id: maven-deploy + env: + OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} + OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} + GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + run: | + # Fail fast: If this step fails, no git operations will occur + mvn -DskipTests=true -DskipChecks=true -DperformRelease=true clean deploy + + - name: Trigger Central Publisher Portal Upload + env: + OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} + OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} + CENTRAL_NAMESPACE: ${{ secrets.CENTRAL_NAMESPACE }} + run: | + echo "Triggering manual upload to Central Publisher Portal..." + + # Create base64 encoded credentials for Basic Auth + CREDENTIALS=$(echo -n "$OSSRH_USERNAME:$OSSRH_PASSWORD" | base64) + + # Make POST request to trigger upload + HTTP_STATUS=$(curl -s -o response.json -w "%{http_code}" \ + -X POST \ + -H "Authorization: Basic $CREDENTIALS" \ + -H "Content-Type: application/json" \ + "https://ossrh-staging-api.central.sonatype.com/manual/upload/defaultRepository/$CENTRAL_NAMESPACE") + + echo "HTTP Status: $HTTP_STATUS" + echo "Response:" + cat response.json + + if [ $HTTP_STATUS -eq 200 ] || [ $HTTP_STATUS -eq 201 ]; then + echo "✅ Successfully triggered upload to Central Publisher Portal" + else + echo "❌ Failed to trigger upload (HTTP $HTTP_STATUS)" + echo "Response details:" + cat response.json + exit 1 + fi + + - name: Collect all POM files for commit + # This step only runs if Maven Central deployment succeeded (fail-fast behavior) + if: success() + run: | + # Add all modified tracked POM files + git add -u **/pom.xml + + - name: Commit release version and push to main branch + # This step only runs if Maven Central deployment succeeded (fail-fast behavior) + if: success() + run: | + git commit -m "Release version ${{ github.event.inputs.release_version }}" + git push origin + + - name: Create and push release tag + # This step only runs if Maven Central deployment and commit succeeded (fail-fast behavior) + if: success() + run: | + git tag -a "v${{ github.event.inputs.release_version }}" -m "Release version ${{ github.event.inputs.release_version }}" + git push origin "v${{ github.event.inputs.release_version }}" + + - name: Update to next snapshot version + # This step only runs after successful tag creation (fail-fast behavior) + if: success() + run: | + mvn versions:set -DnewVersion=${{ github.event.inputs.next_snapshot_version }} + mvn versions:commit + + - name: Update parent POM versions in modules to snapshot + # This step only runs after successful tag creation (fail-fast behavior) + if: success() + run: | + # Update parent version in all child POMs + # Find all pom.xml files except the root pom.xml + for pom in $(find . -name pom.xml ! -path "./pom.xml"); do + if [ -f "$pom" ]; then + mvn versions:update-parent -DparentVersion=${{ github.event.inputs.next_snapshot_version }} -f "$pom" + mvn versions:commit -f "$pom" + fi + done + + - name: Verify snapshot version + if: success() + run: | + echo "Updated version to:" + mvn help:evaluate -Dexpression=project.version -q -DforceStdout + + - name: Commit and push snapshot version + # This step only runs after successful deployment and tag creation (fail-fast behavior) + if: success() + run: | + # Add all modified POM files + git add **/pom.xml + git commit -m "Prepare for next development iteration: ${{ github.event.inputs.next_snapshot_version }}" + git push origin + + - name: Create GitHub Release + # This step only runs after all previous steps succeeded (fail-fast behavior) + if: success() + uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0 + with: + tag_name: "v${{ github.event.inputs.release_version }}" + name: "Release ${{ github.event.inputs.release_version }}" + body: | + Release ${{ github.event.inputs.release_version }} + + This release has been automatically deployed to Maven Central. + + **Artifacts:** + - `org.openhab.tools.sat:sat-plugin:${{ github.event.inputs.release_version }}` + - `org.openhab.tools.sat:sat-extension:${{ github.event.inputs.release_version }}` + - `org.openhab.tools:openhab-codestyle:${{ github.event.inputs.release_version }}` + - `org.openhab.tools.sat.custom-checks:checkstyle-rules:${{ github.event.inputs.release_version }}` + - `org.openhab.tools.sat.custom-checks:pmd-rules:${{ github.event.inputs.release_version }}` + - `org.openhab.tools.sat.custom-checks:findbugs-rules:${{ github.event.inputs.release_version }}` + + **Maven Central - SAT Plugin:** + ```xml + + org.openhab.tools.sat + sat-plugin + ${{ github.event.inputs.release_version }} + + ``` + + **Maven Central - SAT Extension:** + ```xml + + org.openhab.tools.sat + sat-extension + ${{ github.event.inputs.release_version }} + + ``` + + **Maven Central - Codestyle:** + ```xml + + org.openhab.tools + openhab-codestyle + ${{ github.event.inputs.release_version }} + + ``` + draft: false + prerelease: false + + check-central-deployment: + name: Verify Maven Central Deployment + needs: release + runs-on: ubuntu-latest + + steps: + - name: Wait for Maven Central synchronization + run: | + echo "Waiting for artifacts to be synchronized to Maven Central..." + sleep 300 # Wait 5 minutes for initial propagation + + - name: Check Maven Central availability + run: | + RELEASE_VERSION="${{ github.event.inputs.release_version }}" + MAX_ATTEMPTS=12 + ATTEMPT=1 + + while [ $ATTEMPT -le $MAX_ATTEMPTS ]; do + echo "Attempt $ATTEMPT of $MAX_ATTEMPTS: Checking Maven Central for version $RELEASE_VERSION..." + + HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \ + "https://repo1.maven.org/maven2/org/openhab/tools/sat/sat-plugin/$RELEASE_VERSION/sat-plugin-$RELEASE_VERSION.pom") + + if [ $HTTP_STATUS -eq 200 ]; then + echo "✅ Artifact successfully found on Maven Central!" + echo "🔗 Maven Central URL: https://repo1.maven.org/maven2/org/openhab/tools/sat/sat-plugin/$RELEASE_VERSION/" + echo "📦 Maven Central search: https://search.maven.org/artifact/org.openhab.tools.sat/sat-plugin/$RELEASE_VERSION/maven-plugin" + break + else + echo "❌ Artifact not yet available (HTTP $HTTP_STATUS). Waiting..." + if [ $ATTEMPT -eq $MAX_ATTEMPTS ]; then + echo "⚠️ Maximum attempts reached. Deployment may still be in progress." + echo "🕐 It can take up to 2 hours for artifacts to appear on Maven Central." + echo "📋 Check manually at: https://search.maven.org/artifact/org.openhab.tools.sat/sat-plugin/$RELEASE_VERSION/maven-plugin" + else + sleep 300 # Wait 5 minutes between attempts + fi + fi + + ATTEMPT=$((ATTEMPT + 1)) + done