diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..74e8a75d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,169 @@ +name: CI + +on: + push: + branches: [ main, develop ] + pull_request: + branches: [ main, develop ] + +env: + MAVEN_OPTS: -Xmx1024m + +jobs: + test: + name: Test + runs-on: ubuntu-latest + strategy: + matrix: + java-version: [17, 21] + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up JDK ${{ matrix.java-version }} + uses: actions/setup-java@v4 + with: + java-version: ${{ matrix.java-version }} + distribution: 'temurin' + cache: maven + + - name: Cache Maven dependencies + uses: actions/cache@v4 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + + - name: Run tests + run: mvn clean test + + - name: Generate test report + uses: dorny/test-reporter@v1 + if: success() || failure() + with: + name: Maven Tests + path: '**/target/surefire-reports/*.xml' + reporter: java-junit + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: test-results-jdk-${{ matrix.java-version }} + path: | + **/target/surefire-reports/ + **/target/site/ + retention-days: 7 + + build: + name: Build + runs-on: ubuntu-latest + needs: test + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + + - name: Cache Maven dependencies + uses: actions/cache@v4 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + + - name: Build with Maven + run: mvn clean compile package -DskipTests=true + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: build-artifacts + path: | + **/target/*.jar + **/target/*.war + retention-days: 7 + + security: + name: Security Scan + runs-on: ubuntu-latest + if: github.event_name == 'pull_request' + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + + - name: Run OWASP Dependency Check + uses: dependency-check/Dependency-Check_Action@main + with: + project: 'kinde-java-sdk' + path: '.' + format: 'ALL' + args: '--enableRetired --enableExperimental' + + - name: Upload security scan results + uses: actions/upload-artifact@v4 + if: always() + with: + name: security-scan-results + path: reports/ + retention-days: 30 + + quality: + name: Code Quality + runs-on: ubuntu-latest + if: github.event_name == 'pull_request' + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + + - name: Cache Maven dependencies + uses: actions/cache@v4 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + + - name: Run SpotBugs + run: mvn spotbugs:check + + - name: Run PMD + run: mvn pmd:check + + - name: Run Checkstyle + run: mvn checkstyle:check + + - name: Upload quality reports + uses: actions/upload-artifact@v4 + if: always() + with: + name: quality-reports + path: | + **/target/spotbugsXml.xml + **/target/pmd.xml + **/target/checkstyle-result.xml + retention-days: 7 diff --git a/.github/workflows/prerelease.yml b/.github/workflows/prerelease.yml new file mode 100644 index 00000000..9a2ac690 --- /dev/null +++ b/.github/workflows/prerelease.yml @@ -0,0 +1,123 @@ +name: Pre-release + +on: + workflow_dispatch: + inputs: + version: + description: 'Pre-release version (e.g., 2.3.0-alpha.1)' + required: true + type: string + prerelease_type: + description: 'Type of pre-release' + required: true + default: 'alpha' + type: choice + options: + - alpha + - beta + - rc + skip_tests: + description: 'Skip tests during pre-release' + required: false + default: false + type: boolean + +env: + MAVEN_OPTS: -Xmx1024m + +jobs: + prerelease: + name: Pre-release + runs-on: ubuntu-latest + environment: prerelease + permissions: + contents: write + packages: write + id-token: write + issues: write + pull-requests: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + + - name: Cache Maven dependencies + uses: actions/cache@v4 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + + - name: Run tests + if: ${{ !inputs.skip_tests }} + run: | + mvn clean test -DskipTests=false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Build project + run: | + mvn clean compile package -DskipTests=true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Setup GPG + run: | + echo "${{ secrets.GPG_SECRET_KEY }}" | gpg --batch --yes --import + echo "${{ secrets.GPG_PUBLIC_KEY }}" | gpg --batch --yes --import + echo "allow-loopback-pinentry" >> ~/.gnupg/gpg-agent.conf + gpgconf --reload gpg-agent + + - name: Configure Git + run: | + git config --global user.name "Kinde Pre-release Bot" + git config --global user.email "engineering@kinde.com" + + - name: Run JReleaser (Pre-release) + uses: jreleaser/release-action@v1 + with: + version: latest + arguments: | + --config-file jreleaser.yml + --debug + --project-version ${{ inputs.version }} + --release-type prerelease + --prerelease-type ${{ inputs.prerelease_type }} + ${{ inputs.skip_tests && '--skip-tests' || '' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} + OSSRH_TOKEN: ${{ secrets.OSSRH_TOKEN }} + OSSRH_STAGING_PROFILE_ID: ${{ secrets.OSSRH_STAGING_PROFILE_ID }} + GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + GPG_PUBLIC_KEY: ${{ secrets.GPG_PUBLIC_KEY }} + GPG_SECRET_KEY: ${{ secrets.GPG_SECRET_KEY }} + GPG_KEYRING: ${{ secrets.GPG_KEYRING }} + + - name: Upload pre-release artifacts + uses: actions/upload-artifact@v4 + if: always() + with: + name: prerelease-artifacts-${{ inputs.version }} + path: | + jreleaser/output/ + retention-days: 30 + + - name: Create pre-release summary + if: always() + run: | + echo "## Pre-release Summary" >> $GITHUB_STEP_SUMMARY + echo "- **Version**: ${{ inputs.version }}" >> $GITHUB_STEP_SUMMARY + echo "- **Pre-release Type**: ${{ inputs.prerelease_type }}" >> $GITHUB_STEP_SUMMARY + echo "- **Tests Skipped**: ${{ inputs.skip_tests }}" >> $GITHUB_STEP_SUMMARY + echo "- **Workflow**: [View Details](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..5c7e8305 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,123 @@ +name: Release + +on: + workflow_dispatch: + inputs: + version: + description: 'Version to release (leave empty for auto-increment)' + required: false + type: string + release_type: + description: 'Type of release' + required: true + default: 'patch' + type: choice + options: + - patch + - minor + - major + - prerelease + skip_tests: + description: 'Skip tests during release' + required: false + default: false + type: boolean + +env: + MAVEN_OPTS: -Xmx1024m + +jobs: + release: + name: Release + runs-on: ubuntu-latest + environment: production + permissions: + contents: write + packages: write + id-token: write + issues: write + pull-requests: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + + - name: Cache Maven dependencies + uses: actions/cache@v4 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + + - name: Run tests + if: ${{ !inputs.skip_tests }} + run: | + mvn clean test -DskipTests=false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Build project + run: | + mvn clean compile package -DskipTests=true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Setup GPG + run: | + echo "${{ secrets.GPG_SECRET_KEY }}" | gpg --batch --yes --import + echo "${{ secrets.GPG_PUBLIC_KEY }}" | gpg --batch --yes --import + echo "allow-loopback-pinentry" >> ~/.gnupg/gpg-agent.conf + gpgconf --reload gpg-agent + + - name: Configure Git + run: | + git config --global user.name "Kinde Release Bot" + git config --global user.email "engineering@kinde.com" + + - name: Run JReleaser + uses: jreleaser/release-action@v1 + with: + version: latest + arguments: | + --config-file jreleaser.yml + --debug + ${{ inputs.version && format('--project-version {0}', inputs.version) || '' }} + ${{ inputs.release_type != 'patch' && format('--release-type {0}', inputs.release_type) || '' }} + ${{ inputs.skip_tests && '--skip-tests' || '' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} + OSSRH_TOKEN: ${{ secrets.OSSRH_TOKEN }} + OSSRH_STAGING_PROFILE_ID: ${{ secrets.OSSRH_STAGING_PROFILE_ID }} + GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + GPG_PUBLIC_KEY: ${{ secrets.GPG_PUBLIC_KEY }} + GPG_SECRET_KEY: ${{ secrets.GPG_SECRET_KEY }} + GPG_KEYRING: ${{ secrets.GPG_KEYRING }} + + - name: Upload release artifacts + uses: actions/upload-artifact@v4 + if: always() + with: + name: release-artifacts + path: | + jreleaser/output/ + retention-days: 30 + + - name: Create release summary + if: always() + run: | + echo "## Release Summary" >> $GITHUB_STEP_SUMMARY + echo "- **Version**: ${{ inputs.version || 'Auto-incremented' }}" >> $GITHUB_STEP_SUMMARY + echo "- **Release Type**: ${{ inputs.release_type }}" >> $GITHUB_STEP_SUMMARY + echo "- **Tests Skipped**: ${{ inputs.skip_tests }}" >> $GITHUB_STEP_SUMMARY + echo "- **Workflow**: [View Details](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})" >> $GITHUB_STEP_SUMMARY diff --git a/jreleaser.yml b/jreleaser.yml new file mode 100644 index 00000000..87143dab --- /dev/null +++ b/jreleaser.yml @@ -0,0 +1,215 @@ +project: + name: kinde-java-sdk + description: Kinde Java SDK + longDescription: Official Java SDK for Kinde authentication and authorization + website: https://kinde.com + license: MIT + copyright: "© 2024 Kinde" + authors: + - name: Kinde Engineering + email: engineering@kinde.com + links: + homepage: https://kinde.com + documentation: https://kinde.com/docs + repository: https://github.com/kinde-oss/kinde-java-sdk + java: + groupId: com.kinde + artifactId: kinde-parent-pom + version: '{{projectVersion}}' + mainClass: com.kinde.KindeClient + +release: + github: + owner: kinde-oss + name: kinde-java-sdk + tagName: '{{projectVersion}}' + releaseName: '{{projectName}} {{projectVersion}}' + body: | + ## What's Changed + {{changelog}} + + **Full Changelog**: https://github.com/kinde-oss/kinde-java-sdk/compare/{{previousTag}}...{{tagName}} + draft: false + prerelease: + enabled: false + overwrite: false + update: + enabled: true + skipTag: false + skipRelease: false + discussionCategoryName: 'Announcements' + releaseNotes: + enabled: true + +signing: + active: ALWAYS + armored: true + publicKey: '{{env.GPG_PUBLIC_KEY}}' + secretKey: '{{env.GPG_SECRET_KEY}}' + passphrase: '{{env.GPG_PASSPHRASE}}' + +deploy: + maven: + # Portal publisher for releases + mavenCentral: + sonatype: + active: RELEASE + url: https://central.sonatype.com/api/v1/publisher + # JReleaser will read staged artifacts from target/staging-deploy + stagingRepositories: + - target/staging-deploy + # Nexus2 for snapshots (and optionally releases if you prefer) + nexus2: + ossrh: + active: SNAPSHOT + url: https://s01.oss.sonatype.org/service/local + snapshotUrl: https://s01.oss.sonatype.org/content/repositories/snapshots/ + +distributions: + kinde-core: + name: kinde-core + executable: false + artifacts: + - path: 'kinde-core/target/{{distributionArtifactFile}}' + platform: '{{os}}' + java: + groupId: com.kinde + artifactId: kinde-core + version: '{{projectVersion}}' + + kinde-management: + name: kinde-management + executable: false + artifacts: + - path: 'kinde-management/target/{{distributionArtifactFile}}' + platform: '{{os}}' + java: + groupId: com.kinde + artifactId: kinde-management + version: '{{projectVersion}}' + + kinde-j2ee: + name: kinde-j2ee + executable: false + artifacts: + - path: 'kinde-j2ee/target/{{distributionArtifactFile}}' + platform: '{{os}}' + java: + groupId: com.kinde + artifactId: kinde-j2ee + version: '{{projectVersion}}' + + kinde-springboot-core: + name: kinde-springboot-core + executable: false + artifacts: + - path: 'kinde-springboot/kinde-springboot-core/target/{{distributionArtifactFile}}' + platform: '{{os}}' + java: + groupId: com.kinde.spring + artifactId: kinde-springboot-core + version: '{{projectVersion}}' + + kinde-test-utils: + name: kinde-test-utils + executable: false + artifacts: + - path: 'kinde-test-utils/target/{{distributionArtifactFile}}' + platform: '{{os}}' + java: + groupId: com.kinde + artifactId: kinde-test-utils + version: '{{projectVersion}}' + +changelog: + enabled: true + format: '{{formattedChangelog}}' + preset: conventional-commits + categories: + - title: '🚀 Features' + labels: + - 'feature' + - 'enhancement' + - title: '🐛 Bug Fixes' + labels: + - 'fix' + - 'bugfix' + - 'bug' + - title: '🧰 Maintenance' + labels: + - 'chore' + - 'deps' + - 'maintenance' + contributors: + enabled: true + format: '{{contributorName}} ({{contributorLogin}})' + hide: + uncategorized: false + empty: true + sort: + order: ASC + skipMergeCommits: true + links: + enabled: true + format: '{{#formatCommitLink}}{{commitLongHash}}{{/formatCommitLink}}' + issue: 'https://github.com/kinde-oss/kinde-java-sdk/issues/{{issue}}' + commit: 'https://github.com/kinde-oss/kinde-java-sdk/commit/{{hash}}' + scm: 'https://github.com/kinde-oss/kinde-java-sdk/{{branch}}' + +announce: + twitter: + enabled: false + mastodon: + enabled: false + discord: + enabled: false + teams: + enabled: false + slack: + enabled: false + zulip: + enabled: false + gitter: + enabled: false + mattermost: + enabled: false + rocketchat: + enabled: false + telegram: + enabled: false + smtp: + enabled: false + sdkman: + enabled: false + scoop: + enabled: false + chocolatey: + enabled: false + homebrew: + enabled: false + snap: + enabled: false + gofish: + enabled: false + winget: + enabled: false + linkedin: + enabled: false + reddit: + enabled: false + facebook: + enabled: false + youtube: + enabled: false + gitea: + enabled: false + codeberg: + enabled: false + sourceforge: + enabled: false + gitlab: + enabled: false + gitee: + enabled: false + generic: + enabled: false