Repository navigation
Delete .github/workflows/gitlab-sync.yml #50
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 Publish | ||
| on: | ||
| pull_request: | ||
| types: [closed] | ||
| branches: [main] | ||
| concurrency: | ||
| group: release-publish | ||
| cancel-in-progress: false | ||
| jobs: | ||
| release: | ||
| name: Create & Publish Release | ||
| # Only tagged product releases. Merging a CI/docs PR to main without the | ||
| # `release` label must not derive a hotfix tag or publish. | ||
| if: github.event.pull_request.merged == true && contains(join(github.event.pull_request.labels.*.name, ','), 'release') | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: write | ||
| packages: write | ||
| steps: | ||
| - name: Checkout (full history & tags) | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
| - name: Fetch all tags | ||
| run: | | ||
| git fetch --tags --quiet | ||
| echo "Existing tags:" | ||
| git tag -l | sort -V | tail -n 20 || true | ||
| - name: Derive release version (with Hotfix fallback) | ||
| id: version | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| RAW_VERSION=$(grep -m1 '<version>' pom.xml | sed -E 's/.*<version>([^<]+)<\/version>.*/\1/') | ||
| if [[ -z "${RAW_VERSION}" ]]; then | ||
| echo "Could not extract version from pom.xml" | ||
| exit 1 | ||
| fi | ||
| # Strip -SNAPSHOT suffix if present. | ||
| BASE_VERSION="${RAW_VERSION%-SNAPSHOT}" | ||
| echo "Base version from pom: ${BASE_VERSION}" | ||
| # Determine if base version tag already exists. | ||
| if git rev-parse -q --verify "refs/tags/${BASE_VERSION}" >/dev/null; then | ||
| echo "Tag ${BASE_VERSION} already exists. Deriving Hotfix version..." | ||
| i=1 | ||
| while git rev-parse -q --verify "refs/tags/${BASE_VERSION}-Hotfix-${i}" >/dev/null; do | ||
| i=$((i+1)) | ||
| done | ||
| FINAL_VERSION="${BASE_VERSION}-Hotfix-${i}" | ||
| echo "Using hotfix version: ${FINAL_VERSION}" | ||
| echo "hotfix=true" >> "$GITHUB_OUTPUT" | ||
| echo "hotfix_index=${i}" >> "$GITHUB_OUTPUT" | ||
| else | ||
| FINAL_VERSION="${BASE_VERSION}" | ||
| echo "Using base version: ${FINAL_VERSION}" | ||
| echo "hotfix=false" >> "$GITHUB_OUTPUT" | ||
| fi | ||
| echo "raw_version=${RAW_VERSION}" >> "$GITHUB_OUTPUT" | ||
| echo "base_version=${BASE_VERSION}" >> "$GITHUB_OUTPUT" | ||
| echo "version=${FINAL_VERSION}" >> "$GITHUB_OUTPUT" | ||
| - name: Set up JDK 23 (generate settings.xml) | ||
| uses: actions/setup-java@v4 | ||
| with: | ||
| distribution: temurin | ||
| java-version: '25' | ||
| server-id: github | ||
| settings-path: ${{ github.workspace }} | ||
| - name: Cache Maven | ||
| uses: actions/cache@v4 | ||
| with: | ||
| path: ~/.m2/repository | ||
| key: maven-${{ runner.os }}-${{ hashFiles('**/pom.xml') }} | ||
| restore-keys: | | ||
| maven-${{ runner.os }}- | ||
| - name: Set release version in pom.xml | ||
| run: | | ||
| set -e | ||
| mvn -B -s $GITHUB_WORKSPACE/settings.xml versions:set -DnewVersion="${{ steps.version.outputs.version }}" -DgenerateBackupPoms=false | ||
| # Keep the standalone processor module version in lockstep. | ||
| mvn -B -s $GITHUB_WORKSPACE/settings.xml versions:set -f singularitylib-processor/pom.xml -DnewVersion="${{ steps.version.outputs.version }}" -DgenerateBackupPoms=false | ||
| echo "Effective pom version line:" | ||
| grep -m1 '<version>' pom.xml | ||
| - name: Commit version change (if modified) | ||
| run: | | ||
| set -e | ||
| if ! git diff --quiet; then | ||
| git config user.name "github-actions[bot]" | ||
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | ||
| git add pom.xml singularitylib-processor/pom.xml | ||
| git commit -m "chore(release): set version ${{ steps.version.outputs.version }}" | ||
| git push origin HEAD:main | ||
| else | ||
| echo "No changes to commit." | ||
| fi | ||
| - name: Build (package) | ||
| run: | | ||
| mvn -B -s $GITHUB_WORKSPACE/settings.xml -DskipTests install -f singularitylib-processor/pom.xml | ||
| mvn -B -s $GITHUB_WORKSPACE/settings.xml -DskipTests -Pwith-shade package | ||
| - name: Deploy Release to GitHub Packages | ||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| run: | | ||
| mvn -B -s $GITHUB_WORKSPACE/settings.xml -DskipTests deploy -f singularitylib-processor/pom.xml | ||
| mvn -B -s $GITHUB_WORKSPACE/settings.xml -DskipTests deploy | ||
| - name: Create & Push Git Tag | ||
| run: | | ||
| set -e | ||
| TAG="${{ steps.version.outputs.version }}" | ||
| if git rev-parse -q --verify "refs/tags/${TAG}" >/dev/null; then | ||
| echo "Tag ${TAG} already exists unexpectedly (race condition?)." | ||
| exit 1 | ||
| fi | ||
| git config user.name "github-actions[bot]" | ||
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | ||
| git tag -a "${TAG}" -m "Release ${TAG}" | ||
| git push origin "${TAG}" | ||
| - name: Create GitHub Release | ||
| uses: softprops/action-gh-release@v2 | ||
| with: | ||
| tag_name: ${{ steps.version.outputs.version }} | ||
| name: "SingularityLib ${{ steps.version.outputs.version }}" | ||
| generate_release_notes: true | ||
| files: | | ||
| `target/*.jar` | ||
| - name: Summary | ||
| run: | | ||
| echo "Published release ${{ steps.version.outputs.version }}" | ||
| echo "Hotfix: ${{ steps.version.outputs.hotfix }}" | ||
| - name: Bump to next snapshot | ||
| if: always() | ||
| run: | | ||
| set -e | ||
| CURRENT="${{ steps.version.outputs.version }}" | ||
| # Basic semver increment of patch for next snapshot (ignoring hotfix tags) | ||
| CORE="${CURRENT%%-Hotfix-*}" | ||
| IFS='.' read -r MA MI PA <<< "$CORE" | ||
| NEXT_PATCH=$((PA + 1)) | ||
| NEXT_VERSION="${MA}.${MI}.${NEXT_PATCH}-SNAPSHOT" | ||
| mvn -B versions:set -DnewVersion="${NEXT_VERSION}" -DgenerateBackupPoms=false | ||
| mvn -B versions:set -f singularitylib-processor/pom.xml -DnewVersion="${NEXT_VERSION}" -DgenerateBackupPoms=false | ||
| if ! git diff --quiet; then | ||
| git config user.name "github-actions[bot]" | ||
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | ||
| git add pom.xml singularitylib-processor/pom.xml | ||
| git commit -m "chore: prepare next development iteration ${NEXT_VERSION}" | ||
| git push origin HEAD:main | ||
| fi | ||
| publish-central: | ||
| # Publishes the release to Maven Central (Portal API, AUTOMATIC mode). | ||
| # Recipe proven on 2026-08-28 (deployment 270228bf…): | ||
| # stage via deploy file: -> gpg sign -> checksums for EVERY file (incl .asc) | ||
| # -> zip via python zipfile (NEVER jar tool: it injects META-INF manifest | ||
| # that Central rejects) -> POST bundle?publishingType=AUTOMATIC | ||
| # Same `release` label gate as the release job — Central upload must not | ||
| # run for unlabeled merges. | ||
| if: github.event.pull_request.merged == true && contains(join(github.event.pull_request.labels.*.name, ','), 'release') | ||
| needs: release | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
| - name: Setup JDK 25 | ||
| uses: actions/setup-java@v4 | ||
| with: | ||
| distribution: temurin | ||
| java-version: '25' | ||
| - name: Setup GPG (CI-generated key) | ||
| run: | | ||
| mkdir -p ~/.gnupg && chmod 700 ~/.gnupg | ||
| cat > /tmp/keygen.bat <<'KG' | ||
| %no-protection | ||
| Key-Type: RSA | ||
| Key-Length: 4096 | ||
| Name-Real: Singularity Project releases | ||
| Name-Email: [email protected] | ||
| Expire-Date: 0 | ||
| %commit | ||
| KG | ||
| gpg --batch --gen-key /tmp/keygen.bat | ||
| KEY_ID=$(gpg --list-secret-keys --with-colons | awk -F: '/^sec/{print $5; exit}') | ||
| echo "key=$KEY_ID" >> "$GITHUB_OUTPUT" | ||
| gpg --armor --export "$KEY_ID" > /tmp/pubkey.asc | ||
| echo "gpg_public_key=$KEY_ID" >> "$GITHUB_OUTPUT" | ||
| - name: Import / use provided GPG key if supplied instead | ||
| if: env.GPG_PRIVATE_KEY != '' | ||
| shell: bash | ||
| env: | ||
| GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} | ||
| run: | | ||
| echo "$GPG_PRIVATE_KEY" | gpg --batch --import | ||
| - name: Determine release version | ||
| id: version | ||
| run: | | ||
| RAW=$(grep -m1 '<version>' pom.xml | sed -E 's/.*<version>([^<]+)<\/version>.*/\1/') | ||
| VER="${RAW%-SNAPSHOT}" | ||
| echo "version=$VER" >> "$GITHUB_OUTPUT" | ||
| - name: Set release version | ||
| run: | | ||
| mvn -B versions:set -DnewVersion=${{ steps.version.outputs.version }} -DgenerateBackupPoms=false | ||
| mvn -B versions:set -f singularitylib-processor/pom.xml -DnewVersion=${{ steps.version.outputs.version }} -DgenerateBackupPoms=false | ||
| - name: Stage artifacts (file: deploy) | ||
| run: | | ||
| mvn -B clean deploy -DskipTests -DaltDeploymentRepository=central::default::file:$(pwd)/staging | ||
| mvn -B deploy -f singularitylib-processor/pom.xml -DskipTests -DaltDeploymentRepository=central::default::file:$(pwd)/staging | ||
| - name: GPG-sign all artifacts | ||
| env: | ||
| GPG_KEY: ${{ steps.gpg.outputs.key }} | ||
| run: | | ||
| find staging -type f \( -name '*.jar' -o -name '*.pom' \) | while read f; do | ||
| gpg --batch --yes --detach-sign --armor "$f" | ||
| done | ||
| - name: Checksums for every file (incl .asc) | ||
| run: | | ||
| find staging -type f | while read f; do | ||
| [ -f "$f.md5" ] || md5sum "$f" | awk '{print $1}' > "$f.md5" | ||
| [ -f "$f.sha1" ] || sha1sum "$f" | awk '{print $1}' > "$f.sha1" | ||
| done | ||
| - name: Bundle (python zipfile — no META-INF) | ||
| run: | | ||
| python3 - <<'PY' | ||
| import zipfile, os | ||
| with zipfile.ZipFile('bundle.zip', 'w', zipfile.ZIP_DEFLATED) as z: | ||
| for dirpath, _, files in os.walk('staging'): | ||
| for f in files: | ||
| full = os.path.join(dirpath, f) | ||
| z.write(full, os.path.relpath(full, 'staging')) | ||
| print('bundled') | ||
| PY | ||
| - name: Upload to Maven Central | ||
| env: | ||
| CENTRAL_USER: ${{ secrets.SONATYPE_USERNAME }} | ||
| CENTRAL_PASS: ${{ secrets.SONATYPE_PASSWORD }} | ||
| run: | | ||
| curl -s -X POST \ | ||
| -u "${CENTRAL_USER}:${CENTRAL_PASS}" \ | ||
| -F "[email protected]" \ | ||
| "https://central.sonatype.com/api/v1/publisher/upload?publishingType=AUTOMATIC" \ | ||
| -w "\nHTTP %{http_code}\n" | ||