diff --git a/.github/workflows/publish-mvn-pkg-to-gh.yml b/.github/workflows/publish-mvn-pkg-to-gh.yml
new file mode 100644
index 00000000..4b243c94
--- /dev/null
+++ b/.github/workflows/publish-mvn-pkg-to-gh.yml
@@ -0,0 +1,140 @@
+name: Publish Maven Artifacts
+
+# This workflow publishes Maven artifacts to GitHub Packages.
+#
+# Security:
+# - Uses GITHUB_TOKEN (automatically provided by GitHub Actions)
+# - workflow_dispatch requires write access (enforced by GitHub)
+# - Tag pushes require push access (enforced by GitHub)
+# - RC branch pushes require write access (enforced by GitHub)
+# - Consider adding branch protection rules to restrict who can push tags and create rc-* branches
+
+on:
+ workflow_dispatch:
+ push:
+ tags:
+ - 'v*'
+ branches:
+ - 'rc-*'
+
+jobs:
+ publish:
+ name: Publish Maven Artifacts to GitHub Packages
+ runs-on: ubuntu-latest
+ # Security: Only run on authorized triggers
+ # - Tags (v*): Regular releases, anyone with push access can create tags
+ # - RC branches (rc-*): Release candidates, requires write access (includes PR merges)
+ # - workflow_dispatch: Manual trigger, requires write access (checked in step below)
+ permissions:
+ contents: read
+ packages: write
+
+ steps:
+ - name: Verify authorization for manual trigger
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ # For manual triggers, verify the user has write access to the repository
+ # This prevents unauthorized users from triggering the workflow
+ # Note: GitHub will also enforce permissions
+
+ # Check if actor is a member of the organization or has write access
+ # This is a basic check - GitHub will also enforce permissions
+ if [ "${{ github.event.sender.type }}" != "User" ] && [ "${{ github.event.sender.type }}" != "Bot" ]; then
+ echo "❌ ERROR: Unauthorized trigger. Only users and bots can trigger this workflow."
+ exit 1
+ fi
+
+ echo "✓ Authorized trigger by: ${{ github.event.sender.login }}"
+ echo " Actor type: ${{ github.event.sender.type }}"
+ echo " Repository: ${{ github.repository }}"
+ echo ""
+ echo "Note: This workflow requires write access to the repository."
+ echo "GitHub will enforce this permission check before allowing the workflow to run."
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Set up JDK
+ uses: actions/setup-java@v4
+ with:
+ java-version: '21'
+ distribution: 'temurin'
+ cache: 'maven'
+ server-id: github
+ server-username: GITHUB_ACTOR
+ server-password: GITHUB_TOKEN
+
+ - name: Publish Maven Artifacts
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GITHUB_ACTOR: ${{ github.actor }}
+ run: |
+ cd java
+
+ # Determine if RC build; assume it is UNLESS ref is tag starting with v (e.g., v0.5.15)
+ RC_OPTION="--rc"
+ REF_NAME="${{ github.ref_name }}"
+ if [[ "$REF_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+ ]]; then
+ RC_OPTION=""
+ fi
+
+ # Read base version from pom.xml
+ BASE_VERSION=$(sed -n 's|[[:space:]]*\(.*\)|\1|p' pom.xml)
+ if [ -z "$BASE_VERSION" ]; then
+ echo "❌ ERROR: Could not extract from pom.xml '' property. Ensure pom.xml uses \${revision} and has a property."
+ exit 1
+ fi
+
+ # Determine version based on RC_OPTION
+ if [ -z "$RC_OPTION" ]; then
+ # Non-RC build: extract version from tag
+ VERSION="${REF_NAME#v}"
+ echo "✓ Detected version tag: $REF_NAME, extracted version: $VERSION"
+ echo "✓ This is a release build (non-RC)"
+ else
+ # RC build: use version from pom.xml and add -SNAPSHOT suffix
+ VERSION="$BASE_VERSION-SNAPSHOT"
+ echo "✓ Using version from pom.xml: $BASE_VERSION"
+ echo "✓ This is an RC build, final version: $VERSION"
+ fi
+
+ # Build and deploy Maven artifacts with the determined version
+ # Pass -Drevision to override the version in pom.xml
+ echo "Building and deploying with version: $VERSION"
+ if mvn clean deploy -DskipTests -Drevision="$VERSION"; then
+ echo "✓ Maven artifacts published to GitHub Packages"
+ echo "Published version: $VERSION"
+ else
+ echo "❌ Maven deploy failed"
+ exit 1
+ fi
+ - name: Summary
+ if: success()
+ run: |
+ cd java
+
+ # Determine the published version (same logic as publish step)
+ # Determine if RC build; assume it is UNLESS ref is tag starting with v (e.g., v0.5.15)
+ RC_OPTION="--rc"
+ REF_NAME="${{ github.ref_name }}"
+ if [[ "$REF_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+ ]]; then
+ RC_OPTION=""
+ fi
+
+ BASE_VERSION=$(sed -n 's|[[:space:]]*\(.*\)|\1|p' pom.xml)
+
+ if [ -z "$RC_OPTION" ]; then
+ PUBLISHED_VERSION="${REF_NAME#v}"
+ BUILD_TYPE="Release"
+ else
+ PUBLISHED_VERSION="${BASE_VERSION}-SNAPSHOT"
+ BUILD_TYPE="Snapshot (RC)"
+ fi
+
+ echo "## ✅ Successfully published Maven artifacts" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Version:** \`${PUBLISHED_VERSION}\`" >> $GITHUB_STEP_SUMMARY
+ echo "**Build Type:** ${BUILD_TYPE}" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "Artifacts have been published to GitHub Packages." >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "Repository: https://github.com/Worklytics/appengine-pipelines/packages" >> $GITHUB_STEP_SUMMARY
diff --git a/java/pom.xml b/java/pom.xml
index 3f4f8fb8..5d5a558e 100644
--- a/java/pom.xml
+++ b/java/pom.xml
@@ -8,7 +8,7 @@
https://github.com/Worklytics/appengine-pipelines/
- 0.3+worklytics.12
+ ${revision}
jar
@@ -17,6 +17,7 @@
+ 0.3+worklytics.12
UTF-8
[2.18.2, 2.18.3)
2.55