diff --git a/.github/workflows/maven-ci.yml b/.github/workflows/maven-ci.yml index ef4a67ab..de3d9a86 100644 --- a/.github/workflows/maven-ci.yml +++ b/.github/workflows/maven-ci.yml @@ -22,11 +22,6 @@ jobs: uses: actions/setup-java@v1 with: java-version: 1.8 - server-id: ossrh - server-username: OSSRH_JIRA_USERNAME - server-password: OSSRH_JIRA_PASSWORD - gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} - gpg-passphrase: GPG_PASSPHRASE - name: Build with Maven run: mvn clean test cobertura:cobertura @@ -36,18 +31,87 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} - - name: Set up Node.js - uses: actions/setup-node@v2 + prepare_snapshot_version: + name: Prepare Snapshot Version + needs: build + if: ${{ github.repository == 'apache/casbin-jcasbin' && github.event_name == 'push' && github.ref == 'refs/heads/master' }} + runs-on: ubuntu-latest + outputs: + version: ${{ steps.snapshot.outputs.version }} + maven_version: ${{ steps.snapshot.outputs.maven_version }} + basename: ${{ steps.snapshot.outputs.basename }} + previous_tag: ${{ steps.snapshot.outputs.previous_tag }} + steps: + - name: Checkout + uses: actions/checkout@v4 with: - node-version: 20 + fetch-depth: 0 - - name: Semantic Release + - name: Compute snapshot version + id: snapshot run: | - npm install -g @conveyal/maven-semantic-release semantic-release - semantic-release --prepare @conveyal/maven-semantic-release --publish @semantic-release/github,@conveyal/maven-semantic-release --verify-conditions @semantic-release/github,@conveyal/maven-semantic-release - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GPG_KEY_NAME: ${{ secrets.GPG_KEY_NAME }} - GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - OSSRH_JIRA_USERNAME: ${{ secrets.OSSRH_JIRA_USERNAME }} - OSSRH_JIRA_PASSWORD: ${{ secrets.OSSRH_JIRA_PASSWORD }} + LATEST_RELEASE_TAG="$( + git tag --list 'v*' | + grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | + sort -V | + tail -n 1 + )" + + if [ -z "${LATEST_RELEASE_TAG}" ]; then + BASE_VERSION="0.1.0" + else + RELEASE_VERSION="${LATEST_RELEASE_TAG#v}" + MAJOR="${RELEASE_VERSION%%.*}" + REST="${RELEASE_VERSION#*.}" + MINOR="${REST%%.*}" + NEXT_MINOR="$((MINOR + 1))" + BASE_VERSION="${MAJOR}.${NEXT_MINOR}.0" + fi + + ESCAPED_BASE_VERSION="${BASE_VERSION//./\\.}" + LAST_SNAPSHOT_NUMBER="$( + git tag --list "v${BASE_VERSION}-snapshot.*" | + sed -nE "s/^v${ESCAPED_BASE_VERSION}-snapshot\\.([0-9]+)$/\\1/p" | + sort -n | + tail -n 1 + )" + LAST_SNAPSHOT_NUMBER="${LAST_SNAPSHOT_NUMBER:-0}" + NEXT_SNAPSHOT_NUMBER="$((LAST_SNAPSHOT_NUMBER + 1))" + SNAPSHOT_VERSION="v${BASE_VERSION}-snapshot.${NEXT_SNAPSHOT_NUMBER}" + MAVEN_VERSION="${SNAPSHOT_VERSION#v}" + BASENAME="jcasbin-${MAVEN_VERSION}-src" + + echo "version=${SNAPSHOT_VERSION}" >> "${GITHUB_OUTPUT}" + echo "maven_version=${MAVEN_VERSION}" >> "${GITHUB_OUTPUT}" + echo "basename=${BASENAME}" >> "${GITHUB_OUTPUT}" + if [ "${LAST_SNAPSHOT_NUMBER}" -gt 0 ]; then + echo "previous_tag=v${BASE_VERSION}-snapshot.${LAST_SNAPSHOT_NUMBER}" >> "${GITHUB_OUTPUT}" + else + echo "previous_tag=${LATEST_RELEASE_TAG}" >> "${GITHUB_OUTPUT}" + fi + + echo "Computed snapshot version: ${SNAPSHOT_VERSION}" + echo "Computed Maven version: ${MAVEN_VERSION}" + + publish-maven: + name: Publish Maven + needs: prepare_snapshot_version + if: ${{ github.repository == 'apache/casbin-jcasbin' && github.event_name == 'push' && github.ref == 'refs/heads/master' }} + uses: ./.github/workflows/maven-snapshot.yml + with: + maven_version: ${{ needs.prepare_snapshot_version.outputs.maven_version }} + secrets: inherit + + semantic-release: + name: Semantic Release + needs: + - prepare_snapshot_version + - publish-maven + if: ${{ github.repository == 'apache/casbin-jcasbin' && github.event_name == 'push' && github.ref == 'refs/heads/master' }} + permissions: + contents: write + uses: ./.github/workflows/source-snapshot.yml + with: + version: ${{ needs.prepare_snapshot_version.outputs.version }} + basename: ${{ needs.prepare_snapshot_version.outputs.basename }} + previous_tag: ${{ needs.prepare_snapshot_version.outputs.previous_tag }} diff --git a/.github/workflows/maven-snapshot.yml b/.github/workflows/maven-snapshot.yml new file mode 100644 index 00000000..eb11c320 --- /dev/null +++ b/.github/workflows/maven-snapshot.yml @@ -0,0 +1,49 @@ +name: Publish Maven + +on: + workflow_call: + inputs: + maven_version: + required: true + type: string + workflow_dispatch: + inputs: + maven_version: + description: Maven release version to publish, for example 1.2.3-snapshot.1 + required: true + type: string + +permissions: + contents: read + +jobs: + publish-maven: + name: Publish Maven + if: ${{ github.repository == 'apache/casbin-jcasbin' }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up JDK 1.8 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 8 + server-id: ossrh + server-username: OSSRH_JIRA_USERNAME + server-password: OSSRH_JIRA_PASSWORD + gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} + gpg-passphrase: GPG_PASSPHRASE + + - name: Publish Maven + run: | + mvn -B org.codehaus.mojo:versions-maven-plugin:2.16.2:set -DnewVersion="${{ inputs.maven_version }}" -DgenerateBackupPoms=false + mvn -B deploy -DskipTests + env: + GPG_KEY_NAME: ${{ secrets.GPG_KEY_NAME }} + GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + OSSRH_JIRA_USERNAME: ${{ secrets.OSSRH_JIRA_USERNAME }} + OSSRH_JIRA_PASSWORD: ${{ secrets.OSSRH_JIRA_PASSWORD }} diff --git a/.github/workflows/source-release-draft.yml b/.github/workflows/source-release-draft.yml new file mode 100644 index 00000000..89861059 --- /dev/null +++ b/.github/workflows/source-release-draft.yml @@ -0,0 +1,125 @@ +name: Build Source Release Draft + +on: + push: + tags: + - "v*" + +permissions: + contents: write + +jobs: + build-source-release-draft: + if: ${{ github.repository == 'apache/casbin-jcasbin' && !contains(github.ref_name, '-') }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Compute release metadata + id: release + run: | + TAG_NAME="${GITHUB_REF_NAME}" + if ! [[ "${TAG_NAME}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Unsupported release tag: ${TAG_NAME}" >&2 + exit 1 + fi + + VERSION="${TAG_NAME#v}" + BASENAME="jcasbin-${VERSION}-src" + PREVIOUS_TAG="$( + git tag --list 'v*' | + grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | + sort -V | + awk -v current="${TAG_NAME}" ' + $0 == current { + print previous + exit + } + { + previous = $0 + } + ' + )" + + echo "tag=${TAG_NAME}" >> "${GITHUB_OUTPUT}" + echo "version=${VERSION}" >> "${GITHUB_OUTPUT}" + echo "basename=${BASENAME}" >> "${GITHUB_OUTPUT}" + echo "previous_tag=${PREVIOUS_TAG}" >> "${GITHUB_OUTPUT}" + + - name: Generate release notes + run: | + CURRENT_TAG="${{ steps.release.outputs.tag }}" + CURRENT_VERSION="${{ steps.release.outputs.version }}" + PREVIOUS_TAG="${{ steps.release.outputs.previous_tag }}" + RELEASE_DATE="$(date -u +%F)" + RANGE="${CURRENT_TAG}" + + if [ -n "${PREVIOUS_TAG}" ]; then + RANGE="${PREVIOUS_TAG}..${CURRENT_TAG}" + fi + + FEATURES="$(git log --pretty=format:'%s (%h)' "${RANGE}" | grep -Ei '^(feat)(\(.+\))?: ' || true)" + FIXES="$(git log --pretty=format:'%s (%h)' "${RANGE}" | grep -Ei '^(fix)(\(.+\))?: ' || true)" + DOCS="$(git log --pretty=format:'%s (%h)' "${RANGE}" | grep -Ei '^(docs?|doc)(\(.+\))?: ' || true)" + + { + if [ -n "${PREVIOUS_TAG}" ]; then + echo "# [${CURRENT_VERSION}](https://github.com/${GITHUB_REPOSITORY}/compare/${PREVIOUS_TAG}...${CURRENT_TAG}) (${RELEASE_DATE})" + else + echo "# ${CURRENT_VERSION} (${RELEASE_DATE})" + fi + echo + echo "This GitHub release is a draft helper for packaging and release notes." + echo + if [ -n "${PREVIOUS_TAG}" ]; then + echo "Changes since ${PREVIOUS_TAG}." + fi + echo + + if [ -n "${FEATURES}" ]; then + echo "## Features" + echo + printf '%s\n' "${FEATURES}" | sed 's/^/- /' + echo + fi + + if [ -n "${FIXES}" ]; then + echo "## Fixes" + echo + printf '%s\n' "${FIXES}" | sed 's/^/- /' + echo + fi + + if [ -n "${DOCS}" ]; then + echo "## Docs" + echo + printf '%s\n' "${DOCS}" | sed 's/^/- /' + echo + fi + + if [ -z "${FEATURES}${FIXES}${DOCS}" ]; then + echo "## Notes" + echo + echo "- No feat/fix/doc commits were found in this release range." + fi + } > RELEASE_NOTES.md + + - name: Create source archives + run: | + mkdir -p dist + git archive --format=tar.gz --prefix="${{ steps.release.outputs.basename }}/" -o "dist/${{ steps.release.outputs.basename }}.tar.gz" "${{ steps.release.outputs.tag }}" + git archive --format=zip --prefix="${{ steps.release.outputs.basename }}/" -o "dist/${{ steps.release.outputs.basename }}.zip" "${{ steps.release.outputs.tag }}" + + - name: Create draft GitHub release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ steps.release.outputs.tag }} + name: JCasbin ${{ steps.release.outputs.tag }} + body_path: RELEASE_NOTES.md + draft: true + files: | + dist/${{ steps.release.outputs.basename }}.tar.gz + dist/${{ steps.release.outputs.basename }}.zip diff --git a/.github/workflows/source-snapshot.yml b/.github/workflows/source-snapshot.yml new file mode 100644 index 00000000..f764f7f0 --- /dev/null +++ b/.github/workflows/source-snapshot.yml @@ -0,0 +1,113 @@ +name: Semantic Release + +on: + workflow_call: + inputs: + version: + required: true + type: string + basename: + required: true + type: string + previous_tag: + required: false + type: string + default: "" + workflow_dispatch: + inputs: + version: + description: GitHub release tag, for example v1.2.3-snapshot.1 + required: true + type: string + basename: + description: Source archive basename, for example jcasbin-1.2.3-snapshot.1-src + required: true + type: string + previous_tag: + description: Previous tag for release notes + required: false + type: string + +permissions: + contents: write + +jobs: + semantic-release: + name: Semantic Release + if: ${{ github.repository == 'apache/casbin-jcasbin' }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Generate snapshot release notes + run: | + PREVIOUS_TAG="${{ inputs.previous_tag }}" + CURRENT_TAG="${{ inputs.version }}" + CURRENT_VERSION="${CURRENT_TAG#v}" + RELEASE_DATE="$(date -u +%F)" + RANGE="HEAD" + + if [ -n "${PREVIOUS_TAG}" ]; then + RANGE="${PREVIOUS_TAG}..HEAD" + fi + + FEATURES="$(git log --pretty=format:'%s (%h)' "${RANGE}" | grep -Ei '^(feat)(\(.+\))?: ' || true)" + FIXES="$(git log --pretty=format:'%s (%h)' "${RANGE}" | grep -Ei '^(fix)(\(.+\))?: ' || true)" + DOCS="$(git log --pretty=format:'%s (%h)' "${RANGE}" | grep -Ei '^(docs?|doc)(\(.+\))?: ' || true)" + + { + if [ -n "${PREVIOUS_TAG}" ]; then + echo "# [${CURRENT_VERSION}](https://github.com/${GITHUB_REPOSITORY}/compare/${PREVIOUS_TAG}...${CURRENT_TAG}) (${RELEASE_DATE})" + else + echo "# ${CURRENT_VERSION} (${RELEASE_DATE})" + fi + echo + if [ -n "${FEATURES}" ]; then + echo "## Features" + echo + printf '%s\n' "${FEATURES}" | sed 's/^/- /' + echo + fi + + if [ -n "${FIXES}" ]; then + echo "## Fixes" + echo + printf '%s\n' "${FIXES}" | sed 's/^/- /' + echo + fi + + if [ -n "${DOCS}" ]; then + echo "## Docs" + echo + printf '%s\n' "${DOCS}" | sed 's/^/- /' + echo + fi + + if [ -z "${FEATURES}${FIXES}${DOCS}" ]; then + echo "## Notes" + echo + echo "- No feat/fix/doc commits were found in this snapshot range." + fi + } > SNAPSHOT_RELEASE_NOTES.md + + - name: Create source archives + run: | + mkdir -p dist + git archive --format=tar.gz --prefix="${{ inputs.basename }}/" -o "dist/${{ inputs.basename }}.tar.gz" HEAD + git archive --format=zip --prefix="${{ inputs.basename }}/" -o "dist/${{ inputs.basename }}.zip" HEAD + + - name: Create Semantic release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ inputs.version }} + target_commitish: ${{ github.sha }} + name: ${{ inputs.version }} + body_path: SNAPSHOT_RELEASE_NOTES.md + draft: false + prerelease: false + files: | + dist/${{ inputs.basename }}.tar.gz + dist/${{ inputs.basename }}.zip diff --git a/pom.xml b/pom.xml index d491ce59..c36ee335 100644 --- a/pom.xml +++ b/pom.xml @@ -46,13 +46,6 @@ 2.0.16 - - - ossrh - https://central.sonatype.com - - -