name: Java Publish Snapshot to Maven Central env: HUSKY: 0 on: schedule: - cron: "0 7 * * 1-5" # Mon-Fri at 07:00 UTC workflow_dispatch: permissions: contents: read concurrency: group: publish-snapshot cancel-in-progress: false jobs: resolve-source: name: Resolve immutable snapshot source runs-on: ubuntu-latest outputs: source_sha: ${{ steps.source.outputs.sha }} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.sha }} fetch-depth: 1 persist-credentials: false - id: source shell: bash run: | SHA=$(git rev-parse HEAD) echo "sha=$SHA" >> "$GITHUB_OUTPUT" build-linux-arm64-classifier: name: Build Linux ARM64 snapshot classifier needs: resolve-source runs-on: ubuntu-24.04-arm permissions: contents: read outputs: version: ${{ steps.build.outputs.version }} defaults: run: shell: bash working-directory: ./java steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.sha }} fetch-depth: 1 persist-credentials: false - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5 with: java-version: "25" distribution: "microsoft" cache: "maven" - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version: 22 - name: Build and validate linux-arm64 classifier id: build run: | set -euo pipefail SOURCE_COMMIT=$(git rev-parse HEAD) if [ "$SOURCE_COMMIT" != "${{ needs.resolve-source.outputs.source_sha }}" ]; then echo "::error::Checked out $SOURCE_COMMIT instead of the resolved snapshot source." exit 1 fi node copilot-native/scripts/validate-native-host.mjs linux-arm64 mvn -B -pl copilot-native package -DskipTests -Dcopilot.native.libc=glibc VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) JAR="copilot-native/target/copilot-sdk-java-runtime-$VERSION-linux-arm64.jar" PRIMARY_JAR="copilot-native/target/copilot-sdk-java-runtime-$VERSION.jar" test -f "$JAR" node copilot-native/scripts/validate-native-artifact.mjs \ classifier linux-arm64 "$JAR" "$(basename "$JAR")" .. node copilot-native/scripts/validate-native-artifact.mjs placeholder "$PRIMARY_JAR" MANIFEST="copilot-native/target/linux-arm64-$VERSION.sha256" HASH=$(sha256sum "$JAR" | cut -d ' ' -f 1) printf '%s %s' "$HASH" "$(basename "$JAR")" > "$MANIFEST" node copilot-native/scripts/validate-native-artifact.mjs \ checksum "$JAR" "$MANIFEST" "$(basename "$JAR")" echo "version=$VERSION" >> "$GITHUB_OUTPUT" - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: java-native-linux-arm64-snapshot-${{ github.run_id }}-${{ github.run_attempt }} path: | java/copilot-native/target/copilot-sdk-java-runtime-${{ steps.build.outputs.version }}-linux-arm64.jar java/copilot-native/target/linux-arm64-${{ steps.build.outputs.version }}.sha256 if-no-files-found: error retention-days: 1 build-windows-classifier: name: Build Windows snapshot classifier needs: resolve-source runs-on: windows-latest permissions: contents: read outputs: version: ${{ steps.build.outputs.version }} defaults: run: shell: pwsh working-directory: ./java steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.sha }} fetch-depth: 1 persist-credentials: false - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5 with: java-version: "25" distribution: "microsoft" cache: "maven" - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version: 22 - name: Build and validate win32-x64 classifier id: build run: | $sourceCommit = git rev-parse HEAD if ($sourceCommit -ne '${{ needs.resolve-source.outputs.source_sha }}') { throw "Checked out $sourceCommit instead of the resolved snapshot source." } node copilot-native/scripts/validate-native-host.mjs win32-x64 mvn -B -pl copilot-native package -DskipTests $version = mvn help:evaluate "-Dexpression=project.version" -q "-DforceStdout" $jar = "copilot-native/target/copilot-sdk-java-runtime-$version-win32-x64.jar" $primaryJar = "copilot-native/target/copilot-sdk-java-runtime-$version.jar" if (-not (Test-Path -LiteralPath $jar -PathType Leaf)) { throw "Expected Windows classifier was not produced: $jar" } node copilot-native/scripts/validate-native-artifact.mjs classifier win32-x64 $jar ([IO.Path]::GetFileName($jar)) .. node copilot-native/scripts/validate-native-artifact.mjs placeholder $primaryJar $manifest = "copilot-native/target/win32-x64-$version.sha256" $hash = (Get-FileHash -Algorithm SHA256 -LiteralPath $jar).Hash.ToLowerInvariant() "$hash $([IO.Path]::GetFileName($jar))" | Set-Content -NoNewline -Encoding ascii $manifest node copilot-native/scripts/validate-native-artifact.mjs checksum $jar $manifest ([IO.Path]::GetFileName($jar)) "version=$version" | Add-Content $env:GITHUB_OUTPUT - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: java-native-win32-x64-snapshot-${{ github.run_id }}-${{ github.run_attempt }} path: | java/copilot-native/target/copilot-sdk-java-runtime-${{ steps.build.outputs.version }}-win32-x64.jar java/copilot-native/target/win32-x64-${{ steps.build.outputs.version }}.sha256 if-no-files-found: error retention-days: 1 build-windows-arm64-classifier: name: Build Windows ARM64 snapshot classifier needs: resolve-source runs-on: windows-11-arm permissions: contents: read outputs: version: ${{ steps.build.outputs.version }} defaults: run: shell: pwsh working-directory: ./java steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.sha }} fetch-depth: 1 persist-credentials: false - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5 with: java-version: "25" distribution: "microsoft" cache: "maven" - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version: 22 - name: Build and validate win32-arm64 classifier id: build run: | $sourceCommit = git rev-parse HEAD if ($sourceCommit -ne '${{ needs.resolve-source.outputs.source_sha }}') { throw "Checked out $sourceCommit instead of the resolved snapshot source." } node copilot-native/scripts/validate-native-host.mjs win32-arm64 mvn -B -pl copilot-native package -DskipTests $version = mvn help:evaluate "-Dexpression=project.version" -q "-DforceStdout" $jar = "copilot-native/target/copilot-sdk-java-runtime-$version-win32-arm64.jar" $primaryJar = "copilot-native/target/copilot-sdk-java-runtime-$version.jar" if (-not (Test-Path -LiteralPath $jar -PathType Leaf)) { throw "Expected Windows ARM64 classifier was not produced: $jar" } node copilot-native/scripts/validate-native-artifact.mjs classifier win32-arm64 $jar ([IO.Path]::GetFileName($jar)) .. node copilot-native/scripts/validate-native-artifact.mjs placeholder $primaryJar $manifest = "copilot-native/target/win32-arm64-$version.sha256" $hash = (Get-FileHash -Algorithm SHA256 -LiteralPath $jar).Hash.ToLowerInvariant() "$hash $([IO.Path]::GetFileName($jar))" | Set-Content -NoNewline -Encoding ascii $manifest node copilot-native/scripts/validate-native-artifact.mjs checksum $jar $manifest ([IO.Path]::GetFileName($jar)) "version=$version" | Add-Content $env:GITHUB_OUTPUT - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: java-native-win32-arm64-snapshot-${{ github.run_id }}-${{ github.run_attempt }} path: | java/copilot-native/target/copilot-sdk-java-runtime-${{ steps.build.outputs.version }}-win32-arm64.jar java/copilot-native/target/win32-arm64-${{ steps.build.outputs.version }}.sha256 if-no-files-found: error retention-days: 1 build-darwin-classifier: name: Build Darwin snapshot classifier needs: resolve-source runs-on: macos-26 permissions: contents: read outputs: version: ${{ steps.build.outputs.version }} defaults: run: shell: bash working-directory: ./java steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.sha }} fetch-depth: 1 persist-credentials: false - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5 with: java-version: "25" distribution: "microsoft" cache: "maven" - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version: 22 - name: Build and validate darwin-arm64 classifier id: build run: | set -euo pipefail SOURCE_COMMIT=$(git rev-parse HEAD) if [ "$SOURCE_COMMIT" != "${{ needs.resolve-source.outputs.source_sha }}" ]; then echo "::error::Checked out $SOURCE_COMMIT instead of the resolved snapshot source." exit 1 fi node copilot-native/scripts/validate-native-host.mjs darwin-arm64 mvn -B -pl copilot-native package -DskipTests VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) JAR="copilot-native/target/copilot-sdk-java-runtime-$VERSION-darwin-arm64.jar" PRIMARY_JAR="copilot-native/target/copilot-sdk-java-runtime-$VERSION.jar" test -f "$JAR" node copilot-native/scripts/validate-native-artifact.mjs \ classifier darwin-arm64 "$JAR" "$(basename "$JAR")" .. node copilot-native/scripts/validate-native-artifact.mjs placeholder "$PRIMARY_JAR" MANIFEST="copilot-native/target/darwin-arm64-$VERSION.sha256" HASH=$(shasum -a 256 "$JAR" | cut -d ' ' -f 1) printf '%s %s' "$HASH" "$(basename "$JAR")" > "$MANIFEST" node copilot-native/scripts/validate-native-artifact.mjs \ checksum "$JAR" "$MANIFEST" "$(basename "$JAR")" echo "version=$VERSION" >> "$GITHUB_OUTPUT" - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: java-native-darwin-arm64-snapshot-${{ github.run_id }}-${{ github.run_attempt }} path: | java/copilot-native/target/copilot-sdk-java-runtime-${{ steps.build.outputs.version }}-darwin-arm64.jar java/copilot-native/target/darwin-arm64-${{ steps.build.outputs.version }}.sha256 if-no-files-found: error retention-days: 1 deploy-snapshot: name: Publish SNAPSHOT to Maven Central needs: [ resolve-source, build-linux-arm64-classifier, build-windows-classifier, build-windows-arm64-classifier, build-darwin-classifier, ] runs-on: ubuntu-latest defaults: run: shell: bash working-directory: ./java steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.sha }} fetch-depth: 1 persist-credentials: false - uses: ./.github/actions/setup-copilot - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5 with: java-version: "25" distribution: "microsoft" cache: "maven" server-id: central server-username: MAVEN_USERNAME server-password: MAVEN_PASSWORD - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version: 22 - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: name: java-native-linux-arm64-snapshot-${{ github.run_id }}-${{ github.run_attempt }} path: ${{ runner.temp }}/java-native-linux-arm64 - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: name: java-native-win32-x64-snapshot-${{ github.run_id }}-${{ github.run_attempt }} path: ${{ runner.temp }}/java-native-win32-x64 - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: name: java-native-win32-arm64-snapshot-${{ github.run_id }}-${{ github.run_attempt }} path: ${{ runner.temp }}/java-native-win32-arm64 - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: name: java-native-darwin-arm64-snapshot-${{ github.run_id }}-${{ github.run_attempt }} path: ${{ runner.temp }}/java-native-darwin-arm64 - name: Verify version, source, and Linux ARM64 classifier id: linux-arm64-artifact run: | SOURCE_COMMIT=$(git rev-parse HEAD) if [ "$SOURCE_COMMIT" != "${{ needs.resolve-source.outputs.source_sha }}" ]; then echo "::error::Checked out $SOURCE_COMMIT instead of the resolved snapshot source." exit 1 fi VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) if [[ "$VERSION" != *"-SNAPSHOT" ]]; then echo "::error::This workflow only publishes SNAPSHOT versions. Current version: $VERSION" exit 1 fi if [ "$VERSION" != "${{ needs.build-linux-arm64-classifier.outputs.version }}" ]; then echo "::error::Linux ARM64 classifier version does not match deploy version." exit 1 fi ARTIFACT_DIRECTORY="${{ runner.temp }}/java-native-linux-arm64" JAR="$ARTIFACT_DIRECTORY/copilot-sdk-java-runtime-$VERSION-linux-arm64.jar" MANIFEST="$ARTIFACT_DIRECTORY/linux-arm64-$VERSION.sha256" test -f "$JAR" test -f "$MANIFEST" node "$GITHUB_WORKSPACE/java/copilot-native/scripts/validate-native-artifact.mjs" \ checksum "$JAR" "$MANIFEST" "$(basename "$JAR")" node "$GITHUB_WORKSPACE/java/copilot-native/scripts/validate-native-artifact.mjs" \ classifier linux-arm64 "$JAR" "$(basename "$JAR")" "$GITHUB_WORKSPACE" echo "linux_arm64_jar=$JAR" >> "$GITHUB_OUTPUT" echo "version=$VERSION" >> "$GITHUB_OUTPUT" echo "linux_arm64_sha=$(cut -d ' ' -f 1 "$MANIFEST")" >> "$GITHUB_OUTPUT" - name: Verify version, source, and Windows classifier id: windows-artifact run: | SOURCE_COMMIT=$(git rev-parse HEAD) if [ "$SOURCE_COMMIT" != "${{ needs.resolve-source.outputs.source_sha }}" ]; then echo "::error::Checked out $SOURCE_COMMIT instead of the resolved snapshot source." exit 1 fi VERSION="${{ steps.linux-arm64-artifact.outputs.version }}" if [ "$VERSION" != "${{ needs.build-windows-classifier.outputs.version }}" ]; then echo "::error::Windows classifier version does not match deploy version." exit 1 fi ARTIFACT_DIRECTORY="${{ runner.temp }}/java-native-win32-x64" JAR="$ARTIFACT_DIRECTORY/copilot-sdk-java-runtime-$VERSION-win32-x64.jar" MANIFEST="$ARTIFACT_DIRECTORY/win32-x64-$VERSION.sha256" test -f "$JAR" test -f "$MANIFEST" node "$GITHUB_WORKSPACE/java/copilot-native/scripts/validate-native-artifact.mjs" \ checksum "$JAR" "$MANIFEST" "$(basename "$JAR")" node "$GITHUB_WORKSPACE/java/copilot-native/scripts/validate-native-artifact.mjs" \ classifier win32-x64 "$JAR" "$(basename "$JAR")" "$GITHUB_WORKSPACE" echo "windows_jar=$JAR" >> "$GITHUB_OUTPUT" echo "version=$VERSION" >> "$GITHUB_OUTPUT" echo "windows_sha=$(cut -d ' ' -f 1 "$MANIFEST")" >> "$GITHUB_OUTPUT" - name: Verify version, source, and Darwin classifier id: darwin-artifact run: | SOURCE_COMMIT=$(git rev-parse HEAD) if [ "$SOURCE_COMMIT" != "${{ needs.resolve-source.outputs.source_sha }}" ]; then echo "::error::Checked out $SOURCE_COMMIT instead of the resolved snapshot source." exit 1 fi VERSION="${{ steps.windows-artifact.outputs.version }}" if [ "$VERSION" != "${{ needs.build-darwin-classifier.outputs.version }}" ]; then echo "::error::Darwin classifier version does not match deploy version." exit 1 fi ARTIFACT_DIRECTORY="${{ runner.temp }}/java-native-darwin-arm64" JAR="$ARTIFACT_DIRECTORY/copilot-sdk-java-runtime-$VERSION-darwin-arm64.jar" MANIFEST="$ARTIFACT_DIRECTORY/darwin-arm64-$VERSION.sha256" test -f "$JAR" test -f "$MANIFEST" node "$GITHUB_WORKSPACE/java/copilot-native/scripts/validate-native-artifact.mjs" \ checksum "$JAR" "$MANIFEST" "$(basename "$JAR")" node "$GITHUB_WORKSPACE/java/copilot-native/scripts/validate-native-artifact.mjs" \ classifier darwin-arm64 "$JAR" "$(basename "$JAR")" "$GITHUB_WORKSPACE" echo "darwin_jar=$JAR" >> "$GITHUB_OUTPUT" echo "darwin_sha=$(cut -d ' ' -f 1 "$MANIFEST")" >> "$GITHUB_OUTPUT" - name: Verify version, source, and Windows ARM64 classifier id: windows-arm64-artifact run: | SOURCE_COMMIT=$(git rev-parse HEAD) if [ "$SOURCE_COMMIT" != "${{ needs.resolve-source.outputs.source_sha }}" ]; then echo "::error::Checked out $SOURCE_COMMIT instead of the resolved snapshot source." exit 1 fi VERSION="${{ steps.windows-artifact.outputs.version }}" if [ "$VERSION" != "${{ needs.build-windows-arm64-classifier.outputs.version }}" ]; then echo "::error::Windows ARM64 classifier version does not match deploy version." exit 1 fi ARTIFACT_DIRECTORY="${{ runner.temp }}/java-native-win32-arm64" JAR="$ARTIFACT_DIRECTORY/copilot-sdk-java-runtime-$VERSION-win32-arm64.jar" MANIFEST="$ARTIFACT_DIRECTORY/win32-arm64-$VERSION.sha256" test -f "$JAR" test -f "$MANIFEST" node "$GITHUB_WORKSPACE/java/copilot-native/scripts/validate-native-artifact.mjs" \ checksum "$JAR" "$MANIFEST" "$(basename "$JAR")" node "$GITHUB_WORKSPACE/java/copilot-native/scripts/validate-native-artifact.mjs" \ classifier win32-arm64 "$JAR" "$(basename "$JAR")" "$GITHUB_WORKSPACE" echo "windows_arm64_jar=$JAR" >> "$GITHUB_OUTPUT" echo "windows_arm64_sha=$(cut -d ' ' -f 1 "$MANIFEST")" >> "$GITHUB_OUTPUT" - name: Build Linux classifier and deploy complete snapshot run: | VERSION="${{ steps.windows-artifact.outputs.version }}" mvn -B deploy -DskipTests -Dcopilot.native.libc=glibc \ "-Dcopilot.native.external.linux.arm64.classifier.path=${{ steps.linux-arm64-artifact.outputs.linux_arm64_jar }}" \ "-Dcopilot.native.external.win32.classifier.path=${{ steps.windows-artifact.outputs.windows_jar }}" \ "-Dcopilot.native.external.win32.arm64.classifier.path=${{ steps.windows-arm64-artifact.outputs.windows_arm64_jar }}" \ "-Dcopilot.native.external.darwin.classifier.path=${{ steps.darwin-artifact.outputs.darwin_jar }}" LINUX_JAR="copilot-native/target/copilot-sdk-java-runtime-$VERSION-linux-x64.jar" test -f "$LINUX_JAR" node copilot-native/scripts/validate-native-artifact.mjs \ classifier linux-x64 "$LINUX_JAR" "$(basename "$LINUX_JAR")" .. LINUX_SHA=$(sha256sum "$LINUX_JAR" | cut -d ' ' -f 1) GROUP_ID=$(mvn -q -pl copilot-native help:evaluate -Dexpression=project.groupId -DforceStdout) ARTIFACT_ID=$(mvn -q -pl copilot-native help:evaluate -Dexpression=project.artifactId -DforceStdout) POM_VERSION=$(mvn -q -pl copilot-native help:evaluate -Dexpression=project.version -DforceStdout) if [ -z "$GROUP_ID" ] || [ -z "$ARTIFACT_ID" ] || [ "$POM_VERSION" != "$VERSION" ]; then echo "::error::Unexpected copilot-native Maven coordinates: $GROUP_ID:$ARTIFACT_ID:$POM_VERSION (expected version $VERSION)" exit 1 fi { echo "### Snapshot Publish" echo "- **Version:** $VERSION" echo "- **Source commit:** \`${{ needs.resolve-source.outputs.source_sha }}\`" echo "- **Repository:** Maven Central Snapshots" echo "" echo "#### Maven Coordinates" echo "" echo '```xml' echo "" echo " $GROUP_ID" echo " $ARTIFACT_ID" echo " $POM_VERSION" echo "" echo '```' echo "" echo "#### Published Native Classifiers" echo "" echo "| Classifier | Build runner | Artifact | SHA-256 | Status |" echo "| --- | --- | --- | --- | --- |" echo "| \`linux-x64\` | \`ubuntu-latest\` | \`$(basename "$LINUX_JAR")\` | \`$LINUX_SHA\` | Published |" echo "| \`linux-arm64\` | \`ubuntu-24.04-arm\` | \`$(basename "${{ steps.linux-arm64-artifact.outputs.linux_arm64_jar }}")\` | \`${{ steps.linux-arm64-artifact.outputs.linux_arm64_sha }}\` | Published |" echo "| \`win32-x64\` | \`windows-latest\` | \`$(basename "${{ steps.windows-artifact.outputs.windows_jar }}")\` | \`${{ steps.windows-artifact.outputs.windows_sha }}\` | Published |" echo "| \`win32-arm64\` | \`windows-11-arm\` | \`$(basename "${{ steps.windows-arm64-artifact.outputs.windows_arm64_jar }}")\` | \`${{ steps.windows-arm64-artifact.outputs.windows_arm64_sha }}\` | Published |" echo "| \`darwin-arm64\` | \`macos-26\` | \`$(basename "${{ steps.darwin-artifact.outputs.darwin_jar }}")\` | \`${{ steps.darwin-artifact.outputs.darwin_sha }}\` | Published |" } >> "$GITHUB_STEP_SUMMARY" env: MAVEN_USERNAME: ${{ secrets.JAVA_MAVEN_CENTRAL_USERNAME }} MAVEN_PASSWORD: ${{ secrets.JAVA_MAVEN_CENTRAL_PASSWORD }}