Repository navigation
[VERSION] Snapshot v2.2.1-SNAPSHOT (#132) #74
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: Publish Artifacts | |
| on: | |
| push: | |
| branches: | |
| - main | |
| tags: | |
| - 'v*' | |
| pull_request: | |
| types: [opened, synchronize, reopened, labeled] | |
| env: | |
| GRADLE_OPTS: "-Dorg.gradle.jvmargs=-Xmx4g -Dorg.gradle.daemon=false -Dkotlin.incremental=false" | |
| jobs: | |
| publish: | |
| runs-on: macos-latest | |
| if: github.repository == 'episode6/mockspresso2' && (github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'publish-snapshot')) | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up JDK 23 | |
| uses: actions/setup-java@v5 | |
| with: | |
| java-version: '23' | |
| distribution: 'zulu' | |
| - name: Setup Gradle | |
| uses: gradle/actions/setup-gradle@v6 | |
| - name: Clean Project | |
| run: ./gradlew clean | |
| - name: Check and Publish to Maven Local | |
| run: ./gradlew check publishToMavenLocal | |
| env: | |
| ORG_GRADLE_PROJECT_nexusUsername: ${{ secrets.NEXUS_USERNAME }} | |
| ORG_GRADLE_PROJECT_nexusPassword: ${{ secrets.NEXUS_PASSWORD }} | |
| - name: Prepare Sonatype Bundle | |
| run: | | |
| mkdir -p bundle/com/episode6 | |
| cp -r ~/.m2/repository/com/episode6/mockspresso2 bundle/com/episode6/ | |
| # Drop Maven local-repo metadata; remote repos manage their own | |
| # maven-metadata.xml and reject the -local variant (HTTP 400). | |
| find bundle -name "maven-metadata*.xml" -delete | |
| # Sign all artifacts with the dedicated signing subkey. Fail loudly if the | |
| # secret holds anything else — an unpinned gpg would happily fall back to | |
| # whatever signing-capable key it found. | |
| echo "${{ secrets.GPG_MAVEN_KEY }}" | gpg --batch --import | |
| gpg --list-secret-keys 3EBBA2410EE1077E > /dev/null 2>&1 || { | |
| echo "::error::GPG_MAVEN_KEY does not contain signing subkey 3EBBA2410EE1077E" | |
| exit 1 | |
| } | |
| find bundle -type f ! -name "*.asc" ! -name "*.md5" ! -name "*.sha1" ! -name "*.sha256" ! -name "*.sha512" | while read -r file; do | |
| gpg --batch --yes --pinentry-mode loopback --passphrase "${{ secrets.GPG_PASS }}" --local-user '3EBBA2410EE1077E!' --digest-algo SHA512 --detach-sign --armor "$file" || exit 1 | |
| done | |
| # Generate checksums | |
| find bundle -type f ! -name "*.md5" ! -name "*.sha1" ! -name "*.sha256" ! -name "*.sha512" | while read -r file; do | |
| for alg in md5 sha1 sha256 sha512; do | |
| if [ "$alg" == "md5" ]; then md5sum "$file" | cut -d ' ' -f 1 > "$file.md5" | |
| elif [ "$alg" == "sha1" ]; then sha1sum "$file" | cut -d ' ' -f 1 > "$file.sha1" | |
| elif [ "$alg" == "sha256" ]; then sha256sum "$file" | cut -d ' ' -f 1 > "$file.sha256" | |
| elif [ "$alg" == "sha512" ]; then sha512sum "$file" | cut -d ' ' -f 1 > "$file.sha512" | |
| fi | |
| done | |
| done | |
| - name: Create Sonatype Bundle | |
| run: | | |
| cd bundle | |
| zip -r ../sonatype-bundle.zip . | |
| - name: Upload Bundle to GitHub | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: sonatype-bundle | |
| path: sonatype-bundle.zip | |
| compression-level: 0 | |
| - name: Publish to Sonatype Central | |
| env: | |
| NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }} | |
| NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }} | |
| run: | | |
| set -e | |
| # PR-triggered runs (via the publish-snapshot label) may only publish snapshots | |
| if [ "${{ github.event_name }}" == "pull_request" ] && ! find bundle -type f | grep -q -- '-SNAPSHOT'; then | |
| echo "Refusing to publish a non-snapshot version from a pull request" | |
| exit 1 | |
| fi | |
| # If any file path contains -SNAPSHOT treat as a snapshot and upload via the | |
| # timestamped unique-snapshot protocol. Plain PUTs of non-unique snapshot | |
| # filenames only register on a version's first publish — central keeps serving | |
| # the first build forever after that (see scripts/upload-snapshots.py). | |
| if find bundle -type f | grep -q -- '-SNAPSHOT'; then | |
| echo "Snapshot artifacts detected — uploading timestamped snapshot builds to maven-snapshots" | |
| python3 scripts/upload-snapshots.py --bundle bundle \ | |
| --repo-url https://central.sonatype.com/repository/maven-snapshots | |
| else | |
| mv sonatype-bundle.zip ${{ github.event.repository.name }}.zip | |
| SONATYPE_TOKEN=$(printf "%s:%s" "$NEXUS_USERNAME" "$NEXUS_PASSWORD" | base64 | tr -d '\n') | |
| # publishingType=AUTOMATIC publishes to Maven Central as soon as validation | |
| # passes, with no manual step in the portal. Central is append-only — once a | |
| # version publishes it can never be replaced or withdrawn. | |
| DEPLOYMENT_ID=$(curl --fail-with-body --silent --show-error --request POST \ | |
| --header "Authorization: Bearer ${SONATYPE_TOKEN}" \ | |
| --form bundle=@${{ github.event.repository.name }}.zip \ | |
| 'https://central.sonatype.com/api/v1/publisher/upload?publishingType=AUTOMATIC') | |
| echo "Uploaded deployment ${DEPLOYMENT_ID}" | |
| # Upload returns as soon as the bundle is accepted; validation and publication | |
| # run asynchronously. Poll to completion, so a rejected deployment fails the | |
| # release instead of passing silently with nothing on central. | |
| PUBLISHED=false | |
| for _ in $(seq 1 60); do | |
| STATE=$(curl --fail-with-body --silent --show-error --request POST \ | |
| --header "Authorization: Bearer ${SONATYPE_TOKEN}" \ | |
| "https://central.sonatype.com/api/v1/publisher/status?id=${DEPLOYMENT_ID}" \ | |
| | python3 -c 'import json,sys; print(json.load(sys.stdin)["deploymentState"])') | |
| echo " deploymentState=${STATE}" | |
| if [ "$STATE" == "PUBLISHED" ]; then PUBLISHED=true; break; fi | |
| if [ "$STATE" == "FAILED" ]; then | |
| echo "::error::Deployment ${DEPLOYMENT_ID} failed validation" | |
| curl --silent --request POST \ | |
| --header "Authorization: Bearer ${SONATYPE_TOKEN}" \ | |
| "https://central.sonatype.com/api/v1/publisher/status?id=${DEPLOYMENT_ID}" | |
| exit 1 | |
| fi | |
| sleep 30 | |
| done | |
| if [ "$PUBLISHED" != true ]; then | |
| echo "::error::Deployment ${DEPLOYMENT_ID} never reached PUBLISHED (last state: ${STATE})" | |
| exit 1 | |
| fi | |
| echo "Published ${DEPLOYMENT_ID} to Maven Central" | |
| fi | |
| - name: Generate API Docs | |
| if: github.event_name != 'pull_request' | |
| run: ./gradlew dokkaGenerateHtml | |
| - name: Prepare Site Docs | |
| if: github.event_name != 'pull_request' | |
| run: ./gradlew configSite | |
| - name: Deploy root docs to website | |
| if: github.ref_type == 'tag' | |
| uses: JamesIves/github-pages-deploy-action@132898c54c57c7cc6b80eb3a89968de8fc283505 | |
| with: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| BRANCH: site | |
| FOLDER: build/site | |
| TARGET_FOLDER: / | |
| CLEAN: false | |
| - name: Deploy dokka to website | |
| if: github.event_name != 'pull_request' | |
| uses: JamesIves/github-pages-deploy-action@132898c54c57c7cc6b80eb3a89968de8fc283505 | |
| with: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| BRANCH: site | |
| FOLDER: build/dokka/html | |
| TARGET_FOLDER: /docs/${{ github.ref_name }}/ | |
| CLEAN: true |