diff --git a/.github/workflows/extension-attach-artifact-release.yml b/.github/workflows/extension-attach-artifact-release.yml index 02abd964..feae2a05 100644 --- a/.github/workflows/extension-attach-artifact-release.yml +++ b/.github/workflows/extension-attach-artifact-release.yml @@ -166,18 +166,22 @@ jobs: - name: Build and Package if: ${{ inputs.dry_run == false }} shell: bash + env: + MAVEN_PROFILES: ${{ inputs.mavenProfiles }} run: | - mvn -B release:clean release:prepare -Darguments="-Dmaven.javadoc.skip=true -Dmaven.test.skipTests=true -Dmaven.test.skip=true -Dmaven.deploy.skip=true" -DcheckModificationExcludeList=** -DignoreSnapshots=true -DreleaseVersion=${{ github.event.inputs.liquibaseVersion }} -DpushChanges=false -P '${{ inputs.mavenProfiles }}' -DscmServerId=liquibase + mvn -B release:clean release:prepare -Darguments="-Dmaven.javadoc.skip=true -Dmaven.test.skipTests=true -Dmaven.test.skip=true -Dmaven.deploy.skip=true" -DcheckModificationExcludeList=** -DignoreSnapshots=true -DreleaseVersion=${{ github.event.inputs.liquibaseVersion }} -DpushChanges=false -P "$MAVEN_PROFILES" -DscmServerId=liquibase git reset HEAD~ --hard - mvn -B dependency:go-offline clean package -DskipTests=true ${{ inputs.extraMavenArgs }} -P '${{ inputs.mavenProfiles }}' + mvn -B dependency:go-offline clean package -DskipTests=true ${{ inputs.extraMavenArgs }} -P "$MAVEN_PROFILES" - name: Build and Package (dry-run) if: ${{ inputs.dry_run == true }} shell: bash + env: + MAVEN_PROFILES: ${{ inputs.mavenProfiles }} + DRY_RUN_VERSION: ${{ inputs.dry_run_version }} run: | - mvn -B release:clean release:prepare -Darguments="-Dmaven.javadoc.skip=true -Dmaven.test.skipTests=true -Dmaven.test.skip=true -Dmaven.deploy.skip=true" -DcheckModificationExcludeList=** -DignoreSnapshots=true -DreleaseVersion=${{ inputs.dry_run_version }} -DpushChanges=false -P '${{ inputs.mavenProfiles }}' -DscmServerId=liquibase - git reset HEAD~ --hard - mvn -B dependency:go-offline clean package -DskipTests=true ${{ inputs.extraMavenArgs }} -P '${{ inputs.mavenProfiles }}' + mvn -B release:clean release:prepare -DdryRun=true -Darguments="-Dmaven.javadoc.skip=true -Dmaven.test.skipTests=true -Dmaven.test.skip=true -Dmaven.deploy.skip=true" -DcheckModificationExcludeList=** -DignoreSnapshots=true -DreleaseVersion=$DRY_RUN_VERSION -DpushChanges=false -P "$MAVEN_PROFILES" -DscmServerId=liquibase + mvn -B dependency:go-offline clean package -DskipTests=true ${{ inputs.extraMavenArgs }} -P "$MAVEN_PROFILES" - name: Get Artifact ID working-directory: ${{ inputs.artifactPath }} @@ -193,22 +197,19 @@ jobs: echo "artifact_id=$artifact_id" >> $GITHUB_OUTPUT - name: Get Artifact Version - if: ${{ inputs.dry_run == false }} working-directory: ${{ inputs.artifactPath }} id: get-artifact-version shell: bash + env: + DRY_RUN_VERSION: ${{ inputs.dry_run_version }} run: | - artifact_version=$(mvn help:evaluate "-Dexpression=project.version" -q -DforceStdout) + if [ "${{ inputs.dry_run }}" == "true" ]; then + artifact_version="$DRY_RUN_VERSION" + else + artifact_version=$(mvn help:evaluate "-Dexpression=project.version" -q -DforceStdout) + fi echo "artifact_version=$artifact_version" >> $GITHUB_OUTPUT - - name: Get Artifact Version - if: ${{ inputs.dry_run == true }} - working-directory: ${{ inputs.artifactPath }} - id: get-artifact-version-dry-run - shell: bash - run: | - echo "artifact_version=${{ inputs.dry_run_version }}" >> $GITHUB_OUTPUT - - name: Save Artifacts uses: actions/upload-artifact@v4 with: @@ -422,37 +423,52 @@ jobs: if: ${{ env.ARTIFACT_FOUND == '0' && inputs.dry_run == false }} id: build-release-artifacts run: | - mvn -B release:clean release:prepare -Darguments="-Dmaven.javadoc.skip=true -Dmaven.test.skipTests=true -Dmaven.test.skip=true -Dmaven.deploy.skip=true" -DcheckModificationExcludeList=** -DignoreSnapshots=true -DreleaseVersion=${{ github.event.inputs.liquibaseVersion }} -DpushChanges=false -P '${{ inputs.mavenProfiles }}' -DscmServerId=liquibase + mvn -B release:clean release:prepare -Darguments="-Dmaven.javadoc.skip=true -Dmaven.test.skipTests=true -Dmaven.test.skip=true -Dmaven.deploy.skip=true" \ + -DcheckModificationExcludeList=** -DignoreSnapshots=true -DreleaseVersion=${{ github.event.inputs.liquibaseVersion }} -DpushChanges=false -P '${{ inputs.mavenProfiles }}' \ + -DscmServerId=liquibase git reset HEAD~ --hard - # Determine the default branch (master or main) - if git rev-parse --verify origin/master >/dev/null 2>&1; then - DEFAULT_BRANCH="master" - elif git rev-parse --verify origin/main >/dev/null 2>&1; then - DEFAULT_BRANCH="main" - else - echo "Neither master nor main branch found. Exiting." - exit 1 - fi - LAST_COMMIT_HASH=$(git rev-parse origin/$DEFAULT_BRANCH) - mvn clean install -DskipTests -P '${{ inputs.mavenProfiles }}' -DbuildNumber=$LAST_COMMIT_HASH + # Use GitHub's default branch from repository settings + DEFAULT_BRANCH="${{ github.event.repository.default_branch }}" + echo "Using default branch: $DEFAULT_BRANCH" + mvn clean install -DskipTests -P '${{ inputs.mavenProfiles }}' -DbuildNumber=$DEFAULT_BRANCH + + # Generate source and javadoc jars + mvn source:jar javadoc:jar -Dmaven.javadoc.skip=false + + # Copy POM to target directory with versioned name + ARTIFACT_ID=$(mvn help:evaluate -Dexpression=project.artifactId -q -DforceStdout) + VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) + cp pom.xml target/${ARTIFACT_ID}-${VERSION}.pom + echo "Generated artifacts for ${ARTIFACT_ID}-${VERSION}" + + - name: Set pom version to dry_run version + if: ${{ inputs.dry_run == true }} + env: + DRY_RUN_VERSION: ${{ inputs.dry_run_version }} + run: | + mvn versions:set -DnewVersion=$DRY_RUN_VERSION-SNAPSHOT -DgenerateBackupPoms=false -DprocessAllModules=true - name: Build release artifacts (dry-run) if: ${{ inputs.dry_run == true }} id: build-release-artifacts-dry-run + env: + CURRENT_BRANCH: ${{ github.head_ref || github.ref_name }} run: | - mvn -B release:clean release:prepare -Darguments="-Dmaven.javadoc.skip=true -Dmaven.test.skipTests=true -Dmaven.test.skip=true -Dmaven.deploy.skip=true" -DcheckModificationExcludeList=** -DignoreSnapshots=true -DreleaseVersion=${{ inputs.dry_run_version }} -DpushChanges=false -P '${{ inputs.mavenProfiles }}' -DscmServerId=liquibase - git reset HEAD~ --hard - # Determine the default branch (master or main) - if git rev-parse --verify origin/master >/dev/null 2>&1; then - DEFAULT_BRANCH="master" - elif git rev-parse --verify origin/main >/dev/null 2>&1; then - DEFAULT_BRANCH="main" - else - echo "Neither master nor main branch found. Exiting." - exit 1 - fi - LAST_COMMIT_HASH=$(git rev-parse origin/$DEFAULT_BRANCH) - mvn clean install -DskipTests -P '${{ inputs.mavenProfiles }}' -DbuildNumber=$LAST_COMMIT_HASH + mvn -B release:clean release:prepare -DdryRun=true -Darguments="-Dmaven.javadoc.skip=true -Dmaven.test.skipTests=true -Dmaven.test.skip=true -Dmaven.deploy.skip=true" \ + -DcheckModificationExcludeList=** -DignoreSnapshots=true -DreleaseVersion=${{ inputs.dry_run_version }} -DpushChanges=false -P '${{ inputs.mavenProfiles }}' \ + -DscmServerId=liquibase + # Use current branch name for dry runs + echo "Using current branch: $CURRENT_BRANCH" + mvn clean install -DskipTests -P '${{ inputs.mavenProfiles }}' -DbuildNumber=$CURRENT_BRANCH + + # Generate source and javadoc jars + mvn source:jar javadoc:jar -Dmaven.javadoc.skip=false + + # Copy POM to target directory with versioned name + ARTIFACT_ID=$(mvn help:evaluate -Dexpression=project.artifactId -q -DforceStdout) + VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) + cp pom.xml target/${ARTIFACT_ID}-${VERSION}.pom + echo "Generated artifacts for ${ARTIFACT_ID}-${VERSION}" - name: Download multiarchitecture release artifacts if: inputs.combineJars @@ -468,7 +484,6 @@ jobs: LATEST_DRAFT_RELEASE=$(curl -X GET -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" "https://api.github.com/repos/${{ github.repository }}/releases?per_page=1" | jq -r 'if .[].draft == true then .[].id else empty end') echo "Latest Draft Release ID: $LATEST_DRAFT_RELEASE" echo "RELEASE_ID=$LATEST_DRAFT_RELEASE" >> $GITHUB_ENV - - name: List artifacts in release if: ${{ env.RELEASE_ID != '' && env.RELEASE_ID != null && inputs.dry_run == false }} @@ -490,7 +505,6 @@ jobs: curl -X DELETE -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" "https://api.github.com/repos/${{ github.repository }}/releases/assets/$value" echo "Deleted artifact ID: $value" done - - name: Convert escaped newlines and set GPG key run: | GPG_KEY_CONTENT="$(printf '%b' "${{ env.GPG_SECRET }}")" @@ -531,7 +545,8 @@ jobs: working-directory: ${{ inputs.artifactPath }} run: | gpg -K - version=${{ inputs.dry_run_version }} + version=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) + echo "Signing artifacts for version: $version" ${{ env.REPO_ROOT }}/.github/sign_artifact.sh ${{ env.REPO_ROOT }}/${{ inputs.artifactPath }}/target/${{ env.artifact_id }}-${version}.jar ${{ env.REPO_ROOT }}/.github/sign_artifact.sh ${{ env.REPO_ROOT }}/${{ inputs.artifactPath }}/target/${{ env.artifact_id }}-${version}.pom ${{ env.REPO_ROOT }}/.github/sign_artifact.sh ${{ env.REPO_ROOT }}/${{ inputs.artifactPath }}/target/${{ env.artifact_id }}-${version}-javadoc.jar @@ -557,6 +572,20 @@ jobs: ASSET_NAME_PREFIX: "${{ env.artifact_id }}-" ASSET_DIR: ./target + - name: Set artifact path + id: set-artifact-path + if: ${{ inputs.dry_run == true }} + run: echo "ARTIFACT_PATH=${{ inputs.artifactPath || '.' }}" >> $GITHUB_OUTPUT + + - name: Collect artifacts for release (dry-run) + if: ${{ inputs.dry_run == true }} + run: | + mkdir -p /tmp/release-artifacts + # Find and copy all artifacts from target directories (supports multi-module) + find ${{ steps.set-artifact-path.outputs.ARTIFACT_PATH }} -type f \( -name "*.jar" -o -name "*.pom" -o -name "*.asc" \) -path "*/target/*" ! -name "original-*" -exec cp {} /tmp/release-artifacts/ \; + echo "Collected artifacts:" + ls -lh /tmp/release-artifacts/ + - name: Attach Files to Draft Release (dry-run) id: attach-files-dry-run if: ${{ inputs.dry_run == true }} @@ -567,7 +596,7 @@ jobs: body: Dry Run ${{ inputs.dry_run_version }} generate_release_notes: true draft: true - files: ./target/* + files: /tmp/release-artifacts/* - name: Get upload_zip.sh Script File if: inputs.zip == 'true' @@ -582,4 +611,4 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ASSET_NAME_PREFIX: "${{ env.artifact_id }}-" - ASSET_DIR: ./target + ASSET_DIR: ./target \ No newline at end of file diff --git a/.github/workflows/extension-release-published.yml b/.github/workflows/extension-release-published.yml index 190d1acc..773f6146 100644 --- a/.github/workflows/extension-release-published.yml +++ b/.github/workflows/extension-release-published.yml @@ -156,7 +156,7 @@ jobs: uses: robinraju/release-downloader@v1.12 with: tag: "${{ github.event.release.tag_name }}" - fileName: "${{ env.artifact_id }}-*" + fileName: "*" out-file-path: ${{ inputs.artifactPath }} - name: Publish to Maven Central @@ -168,16 +168,27 @@ jobs: version=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) groupId=$(mvn help:evaluate -Dexpression=project.groupId -q -DforceStdout) - # Create Maven repository layout structure for the bundle # Convert groupId dots to directory separators groupPath=$(echo "$groupId" | tr '.' '/') - mkdir -p "bundle/${groupPath}/${{ env.artifact_id }}/${version}" - # Copy all artifacts and their signatures/checksums to proper Maven repository layout - # Skip files containing "-full" in their names - for file in ${{ env.artifact_id }}-${version}*; do - if [[ ! "$file" == *"-full"* ]]; then - cp "$file" "bundle/${groupPath}/${{ env.artifact_id }}/${version}/" + # Process all JAR files (supports multi-module projects) + for jar_file in *-${version}.jar; do + if [ -f "$jar_file" ] && [[ ! "$jar_file" =~ (sources|javadoc)\.jar$ ]]; then + # Extract artifact name (remove version and .jar) + artifact_name="${jar_file%-${version}.jar}" + echo "Processing artifact: $artifact_name" + + # Create Maven repository layout structure for this artifact + mkdir -p "bundle/${groupPath}/${artifact_name}/${version}" + + # Copy all files for this artifact (jar, pom, sources, javadoc, signatures, checksums) + # Skip files containing "-full" in their names + for file in ${artifact_name}-${version}*; do + if [[ ! "$file" == *"-full"* ]] && [ -f "$file" ]; then + cp "$file" "bundle/${groupPath}/${artifact_name}/${version}/" + echo " Copied: $file" + fi + done fi done @@ -276,7 +287,7 @@ jobs: "enabled": "true" }, "snapshots": { - "enabled": "false" + "enabled": "true" } } ] @@ -313,27 +324,107 @@ jobs: uses: robinraju/release-downloader@v1.12 with: releaseId: "${{ inputs.dry_run_release_id }}" - fileName: "${{ env.artifact_id }}-*" + fileName: "*" out-file-path: ${{ inputs.artifactPath }} + - name: Rename SNAPSHOTS to dry_run version + working-directory: ${{ inputs.artifactPath }} + run: | + # Validate and sanitize dry_run_version input (Maven-style: letters, digits, dots, hyphens, underscores) + raw_version="${{ inputs.dry_run_version }}" + if [[ ! "$raw_version" =~ ^[a-zA-Z0-9._-]+$ ]]; then + echo "ERROR: Invalid dry_run_version format: '$raw_version'" + echo "Version must contain only letters, digits, dots, hyphens, and underscores" + exit 1 + fi + version="$raw_version" + echo "Validated version: $version" + + # Rename all SNAPSHOT files (supports both single and multi-module projects) + for file in *-SNAPSHOT*; do + if [ -f "$file" ]; then + # Remove -SNAPSHOT- and -SNAPSHOT from filenames + new_file=$(echo "$file" | sed "s/-SNAPSHOT-/-/g" | sed "s/-SNAPSHOT//g") + if [ "$file" != "$new_file" ]; then + echo "Renaming: $file -> $new_file" + mv "$file" "$new_file" + fi + fi + done + + # Find and update all pom files in current directory (supports multi-module) + ls -l *.pom || echo "No POM files found" + + # Use sanitized version variable with quoted glob pattern to prevent glob expansion + pom_pattern="*-${version}.pom" + pom_files_found=false + for pom_file in $pom_pattern; do + # Check if glob pattern matched actual files + if [ -f "$pom_file" ]; then + pom_files_found=true + echo "Updating $pom_file - removing -SNAPSHOT from version tags" + sed -i 's/\(.*\)-SNAPSHOT<\/version>/\1<\/version>/g' "$pom_file" + echo "✓ Updated $pom_file" + fi + done + + # Fail if no files matched the pattern + if [ "$pom_files_found" = false ]; then + echo "ERROR: No POM files matching pattern '$pom_pattern' were found" + exit 1 + fi + - name: Publish to Maven Central working-directory: ${{ inputs.artifactPath }} env: MAVEN_USERNAME: ${{ env.REPO_LIQUIBASE_NET_USER }} MAVEN_PASSWORD: ${{ env.REPO_LIQUIBASE_NET_PASSWORD }} + DRY_RUN_VERSION: ${{ inputs.dry_run_version }} run: | - version=${{ inputs.dry_run_version }} - mvn -B org.apache.maven.plugins:maven-deploy-plugin:3.0.0-M1:deploy-file \ - -Durl=https://repo.liquibase.net/repository/dry-run-sonatype-nexus-staging/ \ - -DrepositoryId=dry-run-sonatype-nexus-staging \ - -DpomFile=${{ env.artifact_id }}-${version}.pom \ - -DgeneratePom=false \ - -Dfile=${{ env.artifact_id }}-${version}.jar \ - -Dsources=${{ env.artifact_id }}-${version}-sources.jar \ - -Djavadoc=${{ env.artifact_id }}-${version}-javadoc.jar \ - -Dfiles=${{ env.artifact_id }}-${version}.jar.asc,${{ env.artifact_id }}-${version}-sources.jar.asc,${{ env.artifact_id }}-${version}-javadoc.jar.asc,${{ env.artifact_id }}-${version}.pom.asc \ - -Dtypes=jar.asc,jar.asc,jar.asc,pom.asc \ - -Dclassifiers=,sources,javadoc, + # Validate and sanitize DRY_RUN_VERSION input (Maven-style: letters, digits, dots, hyphens, underscores) + raw_version="$DRY_RUN_VERSION" + if [[ ! "$raw_version" =~ ^[a-zA-Z0-9._-]+$ ]]; then + echo "ERROR: Invalid dry_run_version format: '$raw_version'" + echo "Version must contain only letters, digits, dots, hyphens, and underscores" + exit 1 + fi + version="$raw_version" + echo "Validated version: $version" + + # Use sanitized version variable with quoted glob pattern to prevent glob expansion + jar_pattern="*-${version}.jar" + jar_files_found=false + + # Find all JAR files (excluding sources and javadoc) and deploy each (supports multi-module) + for jar_file in $jar_pattern; do + # Check if glob pattern matched actual files + if [ -f "$jar_file" ] && [[ ! "$jar_file" =~ (sources|javadoc)\.jar$ ]]; then + jar_files_found=true + # Extract artifact name (remove version and .jar) + artifact_name="${jar_file%-${version}.jar}" + echo "Publishing artifact: $artifact_name" + + # Deploy with all associated files (quote all variable expansions to prevent injection) + mvn -B org.apache.maven.plugins:maven-deploy-plugin:3.0.0-M1:deploy-file \ + -Durl=https://repo.liquibase.net/repository/dry-run-sonatype-nexus-staging/ \ + -DrepositoryId=dry-run-sonatype-nexus-staging \ + -DpomFile="${artifact_name}-${version}.pom" \ + -DgeneratePom=false \ + -Dfile="${artifact_name}-${version}.jar" \ + -Dsources="${artifact_name}-${version}-sources.jar" \ + -Djavadoc="${artifact_name}-${version}-javadoc.jar" \ + -Dfiles="${artifact_name}-${version}.jar.asc,${artifact_name}-${version}-sources.jar.asc,${artifact_name}-${version}-javadoc.jar.asc,${artifact_name}-${version}.pom.asc" \ + -Dtypes=jar.asc,jar.asc,jar.asc,pom.asc \ + -Dclassifiers=,sources,javadoc, + echo "✓ Published $artifact_name" + fi + done + + # Fail if no JAR files matched the pattern + if [ "$jar_files_found" = false ]; then + echo "ERROR: No JAR files matching pattern '$jar_pattern' were found" + exit 1 + fi deploy_xsd: if: inputs.nameSpace != '' && inputs.deployToMavenCentral == true && inputs.dry_run == false