diff --git a/.github/actions/cleanup-macos-runner/action.yml b/.github/actions/cleanup-macos-runner/action.yml deleted file mode 100644 index c5ac56553ae8..000000000000 --- a/.github/actions/cleanup-macos-runner/action.yml +++ /dev/null @@ -1,53 +0,0 @@ -# action.yml -name: 'Cleanup macOS Runner' -description: 'Cleans up macos runner resources' -runs: - using: 'composite' - steps: - - name: Show Disk Usage - shell: bash - run: | - echo '# df -h' - df -h - - echo "Runner OS: $RUNNER_OS" - - echo '# du -sh /Users/runner' - sudo du -sh /Users/runner || true - - - name: Clean Homebrew cache - shell: bash - run: | - echo 'Clean Homebrew cache' - brew cleanup -s - rm -rf "$(brew --cache)" - - - name: Check directory - shell: bash - run: | - removeIfExists() { - local file=$1 - [[ -e $file ]] && time sudo rm -rf $1 || true - } - - removeIfExists ${HOME}/.cache - removeIfExists ${HOME}/Library/Logs - removeIfExists ${HOME}/Library/Caches - removeIfExists ${HOME}/work/_temp - removeIfExists ${HOME}/.cargo/bin/cargo - removeIfExists ${HOME}/.ghcup/bin/ghc - removeIfExists ${HOME}/Library/Android/sdk - - removeIfExists /usr/local/bin/pipx - removeIfExists /usr/bin/swift - removeIfExists /usr/local/bin/dotnet - removeIfExists /usr/local/Caskroom/ - - - name: Show Disk Usage - shell: bash - run: | - echo "# df -h" - df -h - - echo '# du -sh /Users/runner' - sudo du -sh /Users/runner || true diff --git a/.github/actions/cleanup-runner/action.yml b/.github/actions/cleanup-runner/action.yml index 606544be5262..69f11a94e736 100644 --- a/.github/actions/cleanup-runner/action.yml +++ b/.github/actions/cleanup-runner/action.yml @@ -1,72 +1,108 @@ -# action.yml name: 'Cleanup Runner' description: 'Cleans up runner resources' -author: 'victoralfaro-dotcms' runs: using: 'composite' steps: - - name: Show Disk Usage + - name: Show Initial Disk Usage shell: bash run: | - echo '# df -h' + echo '# Initial Disk Usage' df -h + echo "Runner OS: $RUNNER_OS" - echo '# docker images' - docker images || true - - echo '# du -sh /home/runner' - sudo du -sh /home/runner || true + if [[ "$RUNNER_OS" == "macOS" ]]; then + HOME_DIR="/Users/runner" + echo '# du -sh $HOME_DIR' + sudo du -sh $HOME_DIR || true + elif [[ "$RUNNER_OS" == "Linux" ]]; then + HOME_DIR="/home/runner" + echo '# docker images' + docker images || true + echo '# du -sh $HOME_DIR' + sudo du -sh $HOME_DIR || true + fi - - name: Clean apt cache + - name: Clean Cache shell: bash run: | - echo 'Clean apt cache' - time sudo apt-get clean -y - time sudo apt-get autoclean -y - time sudo apt-get autoremove -y - time sudo rm -rf /var/lib/apt/lists/* + if [[ "$RUNNER_OS" == "macOS" ]]; then + echo 'Clean Homebrew cache' + brew cleanup -s + rm -rf "$(brew --cache)" + elif [[ "$RUNNER_OS" == "Linux" ]]; then + echo 'Clean apt cache' + sudo apt-get clean -y + sudo apt-get autoclean -y + sudo apt-get autoremove -y + sudo rm -rf /var/lib/apt/lists/* + fi - name: Cleanup Docker shell: bash run: | - echo 'Cleanup Docker' - time docker system prune -f - time docker volume prune -f - time docker image prune -f - time docker container prune -f - time docker network prune -f + if [[ "$RUNNER_OS" == "Linux" ]] || [[ "$RUNNER_OS" == "macOS" ]]; then + echo 'Cleanup Docker' + docker system prune -f + docker volume prune -f + docker image prune -f + docker container prune -f + docker network prune -f + fi - name: Reclaim Disk Space shell: bash run: | removeIfExists() { local file=$1 - [[ -e $file ]] && time sudo rm -rf $1 || true + [[ -e $file ]] && sudo rm -rf $1 || true } - - removeIfExists /usr/share/dotnet - removeIfExists /usr/share/swift - removeIfExists /usr/local/lib/android - removeIfExists /opt/ghc - removeIfExists /opt/pipx - removeIfExists /opt/hostedtoolcache/CodeQL - removeIfExists /imagegeneration/installers/go-* - removeIfExists /imagegeneration/installers/node-* - removeIfExists /imagegeneration/installers/python-* - - removeIfExists /home/runner/work/_temp/* - removeIfExists /home/runner/work/_tool/* - removeIfExists /home/runner/work/_config/* + if [[ "$RUNNER_OS" == "macOS" ]]; then + HOME_DIR="/Users/runner" + removeIfExists ${HOME_DIR}/.cache + removeIfExists ${HOME_DIR}/Library/Logs + removeIfExists ${HOME_DIR}/Library/Caches + removeIfExists ${HOME_DIR}/work/_temp + removeIfExists ${HOME_DIR}/.cargo/bin/cargo + removeIfExists ${HOME_DIR}/.ghcup/bin/ghc + removeIfExists ${HOME_DIR}/Library/Android/sdk + + removeIfExists /usr/local/bin/pipx + removeIfExists /usr/bin/swift + removeIfExists /usr/local/bin/dotnet + removeIfExists /usr/local/Caskroom/ + elif [[ "$RUNNER_OS" == "Linux" ]]; then + HOME_DIR="/home/runner" + removeIfExists /usr/share/dotnet + removeIfExists /usr/share/swift + removeIfExists /usr/local/lib/android + removeIfExists /opt/ghc + removeIfExists /opt/pipx - - name: Show Disk Usage + removeIfExists /opt/hostedtoolcache/CodeQL + removeIfExists /imagegeneration/installers/go-* + removeIfExists /imagegeneration/installers/node-* + removeIfExists /imagegeneration/installers/python-* + + removeIfExists ${HOME_DIR}/work/_temp/* + removeIfExists ${HOME_DIR}/work/_tool/* + removeIfExists ${HOME_DIR}/work/_config/* + fi + + - name: Show Final Disk Usage shell: bash run: | - echo "# df -h" + echo '# Final Disk Usage' df -h - echo '# docker images' - docker images || true - - echo '# du -sh /home/runner' - sudo du -sh /home/runner || true + if [[ "$RUNNER_OS" == "macOS" ]]; then + HOME_DIR="/Users/runner" + echo '# du -sh $HOME_DIR' + sudo du -sh $HOME_DIR || true + elif [[ "$RUNNER_OS" == "Linux" ]]; then + HOME_DIR="/home/runner" + echo '# docker images' + docker images || true + echo '# du -sh $HOME_DIR' + sudo du -sh $HOME_DIR || true + fi \ No newline at end of file diff --git a/.github/actions/deploy-artifact-jfrog/action.yml b/.github/actions/deploy-artifact-jfrog/action.yml index b4fbd09946a5..aa2e6c55bfc3 100644 --- a/.github/actions/deploy-artifact-jfrog/action.yml +++ b/.github/actions/deploy-artifact-jfrog/action.yml @@ -37,61 +37,20 @@ runs: steps: - uses: actions/checkout@v4 - - name: 'Set up JDK' - uses: actions/setup-java@v4 - with: - java-version: 11 - distribution: temurin + - name: Setup Java # Uses .sdkmanrc file + id: sdkman-java + uses: sdkman/sdkman-action@b1f9b696c79148b66d3d3a06f7ea801820318d0f - name: Install xmllint run: | sudo apt-get update && sudo apt-get install -y libxml2-utils shell: bash - - name: 'Get Date' - id: get-date - run: | - echo "date=$(/bin/date -u "+%Y-%m")" >> $GITHUB_OUTPUT - shell: bash - - - name: Download Build Artifact - id: data-download - uses: dawidd6/action-download-artifact@v3.1.4 + - uses: ./.github/actions/maven-job with: - github_token: ${{ inputs.github-token }} - workflow_search: true - commit: ${{ github.sha }} - workflow_conclusion: success - search_artifacts: true - dry_run: true - name: maven-repo - path: . - if_no_artifact_found: warn - - - name: 'Check if artifact exists' - id: check - run: | - build_artifact_exists=${{ steps.data-download.outputs.found_artifact }} - if [[ ${build_artifact_exists} == "true" ]]; then - run_id=`echo '${{ steps.data-download.outputs.artifacts }}' | jq -r '.[0].workflow_run.id'` - found_artifacts=true - echo "Artifact Run id: $run_id" - else - echo "No artifact found" - run_id="${{ github.run_id }}" - found_artifacts=false - fi - echo "run_id=$run_id" >> $GITHUB_OUTPUT - echo "found_artifacts=$found_artifacts" >> $GITHUB_OUTPUT - shell: bash + stage-name: "Deploy Artifacts Validate" + maven-args: "validate" # We don't need to build just get the repo and use validate to check everything exists - - name: 'Download Maven Repo' - uses: actions/download-artifact@v4 - with: - run-id: ${{ steps.check.outputs.run_id }} - github-token: ${{ inputs.github-token }} - name: maven-repo - path: ~/.m2/repository - uses: jfrog/setup-jfrog-cli@v4 @@ -213,7 +172,7 @@ runs: echo "::endgroup::" shell: bash - - name: + - name: 'JFrog CLI context' env: ARTIFACTORY_URL: ${{ inputs.artifactory-url || steps.maven-artifact-repository.outputs.url }} ARTIFACTORY_ACCESS_TOKEN: ${{ inputs.artifactory-access-token }} diff --git a/.github/actions/maven-job/action.yml b/.github/actions/maven-job/action.yml new file mode 100644 index 000000000000..fc688efca60c --- /dev/null +++ b/.github/actions/maven-job/action.yml @@ -0,0 +1,299 @@ +name: 'Maven Job' +description: 'Setup and run a Maven job' +inputs: + needs-docker-image: + description: 'The runner needs the built dotCMS docker image' + required: true + default: 'false' + cleanup-runner: + description: 'The runner requires extra disk space' + required: true + default: 'false' + generate-artifacts: + description: 'Generate artifacts for the job' + required: true + default: 'false' + generate-docker: + description: 'Generate docker artifact' + required: true + default: 'false' + needs-history: + description: 'The runner needs the full git history' + required: true + default: 'false' + requires-node: + description: 'The job requires Node.js' + required: true + default: 'true' + cache-sonar: + description: 'Cache the SonarQube files' + required: false + default: 'false' + require-master: + description: 'Require the master tag to run this action' + required: true + default: 'false' + dotcms-license: + description: 'The license key for dotCMS' + required: false + default: '' + artifacts-from: + description: 'Download artifacts from a previous job' + required: false + default: '' + github-token: + description: 'GitHub token for authentication' + required: true + restore-classes: + description: 'Restore build classes' + required: false + default: 'false' + stage-name: + description: 'Stage name for the build' + required: true + maven-args: + description: 'Arguments for Maven build' + required: true + generates-test-results: + description: 'Generate test results artifacts' + required: false + default: 'false' + native: + description: 'Build native image. Ensures that GraalVM is installed and adds correct parameters' + required: true + default: 'false' + version: + description: 'The version of the build' + required: false + default: '1.0.0-SNAPSHOT' + java-version: + description: 'The version of Java to install' + required: false + graalvm-version: + description: 'Override the sdkman version of GraalVM to install' + required: false + require-graalvm: + description: 'Require GraalVM to be installed' + required: true + default: 'false' +runs: + using: 'composite' + steps: + - name: Prepare Runner + uses: ./.github/actions/prepare-runner + with: + cleanup-runner: ${{ inputs.cleanup-runner }} + require-master: ${{ inputs.require-master }} + java-version: ${{ inputs.java-version }} + require-graalvm: ${{ inputs.native || inputs.require-graalvm }} + graalvm-version: ${{ inputs.graalvm-version }} + - id: setup-license + if: ${{ inputs.dotcms-license != '' }} + name: Setup License + shell: bash + env: + DOTCMS_LICENSE_KEY: ${{ inputs.dotcms-license }} + run: | + DOTCMS_LICENSE_PATH=~/.dotcms/license + mkdir -p ${DOTCMS_LICENSE_PATH} + echo "${DOTCMS_LICENSE_KEY}" > ${DOTCMS_LICENSE_PATH}/license.dat + echo "DOTCMS_LICENSE_FILE=${DOTCMS_LICENSE_PATH}/license.dat" >> "$GITHUB_ENV" + + - id: get-maven-month-key + name: Get Maven Month Cache Key + shell: bash + run: | + echo "month-key=$(/bin/date -u "+%Y-%m")" >> $GITHUB_OUTPUT + + - id: restore-cache-maven + name: Restore Maven Repository Cache + if: ${{ inputs.artifacts-from == '' }} + uses: actions/cache/restore@v4 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-mavencore-${{ steps.get-maven-month-key.outputs.month-key }} + restore-keys: | + ${{ runner.os }}-mavencore- + + - id: restore-cache-node + name: Restore Node Binary Cache + if: ${{ inputs.requires-node == 'true' }} + uses: actions/cache@v4 + with: + path: installs + key: node-binary-${{ hashFiles('core-web/.nvmrc') }} + + - id: restore-cache-yarn + name: Restore Yarn Cache + if: ${{ inputs.requires-node == 'true' }} + uses: actions/cache/restore@v4 + with: + path: ~/.cache/yarn + key: yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: yarn- + + - id: cache-sonar + name: Cache SonarQube Packages + if: ${{ inputs.cache-sonar == 'true' }} + uses: actions/cache@v4 + with: + path: ~/.sonar/cache + key: ${{ runner.os }}-sonar + restore-keys: ${{ runner.os }}-sonar + + - id: restore-artifact-maven-repo + name: Restore Maven Build Repo + if: ${{ inputs.artifacts-from != '' }} + uses: actions/download-artifact@v4 + with: + run-id: ${{ inputs.artifacts-from }} + github-token: ${{ inputs.github-token }} + name: maven-repo + path: ~/.m2/repository + + - id: restore-artifact-docker-image + name: Restore Docker Image + if: ${{ inputs.needs-docker-image == 'true' }} + uses: actions/download-artifact@v4 + with: + name: docker-image + path: /tmp/docker-image + + - name: Load Docker image from tar file + shell: bash + if: ${{ inputs.needs-docker-image == 'true' }} + run: docker load < /tmp/docker-image/image.tar + + - id: restore-artifact-classes + name: Restore Classes + if: ${{ inputs.restore-classes == 'true' }} + uses: actions/download-artifact@v4 + with: + run-id: ${{ inputs.artifacts-from }} + github-token: ${{ inputs.github-token }} + name: "build-classes" + + - id: run-maven-build + name: Run Maven Build + shell: ${{ runner.os == 'Windows' && 'pwsh' || 'bash' }} + run: | + DEFAULT_ARGS="-e -B --no-transfer-progress --show-version -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -Pprod" + MAVEN_ARGS="${{ inputs.maven-args }}" + if [[ "${{ inputs.generate-docker }}" == "true" ]]; then + DEFAULT_ARGS="$DEFAULT_ARGS -Ddocker.buildArchiveOnly=dotCMS/target" + fi + if [[ "${{ inputs.native }}" == "true" ]]; then + DEFAULT_ARGS="$DEFAULT_ARGS -Pnative" + fi + FINAL_ARGS=$(echo "$DEFAULT_ARGS $MAVEN_ARGS" | tr ' ' '\n' | awk '!seen[$0]++' | tr '\n' ' ') + + if [[ "${{ runner.os }}" == "Windows" && "${{ inputs.native }}" == "true" ]]; then + echo "Building Maven with args $FINAL_ARGS" + cmd /c 'call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" && .\mvnw.cmd $FINAL_ARGS --file pom.xml' + elif [[ "${{ runner.os }}" == "Windows" ]]; then + echo "Building Maven with args $FINAL_ARGS" + .\mvnw.cmd $FINAL_ARGS --file pom.xml + else + echo "Building Maven with args $FINAL_ARGS" + ./mvnw $FINAL_ARGS --file pom.xml + fi + + - id: persist-maven-repo + name: Persist Maven Repo + if: ${{ inputs.generate-artifacts == 'true' }} + uses: actions/upload-artifact@v4 + with: + name: maven-repo + path: ~/.m2/repository + + - id: persist-docker-build-context + name: Persist Docker Build Context + if: ${{ inputs.generate-docker == 'true' }} + uses: actions/upload-artifact@v4 + with: + name: docker-build-context + path: dotCMS/target/docker-build.tar + + - id: save-docker-image + name: Save Docker Image to Tar File + if: ${{ inputs.generate-docker == 'true' }} + shell: bash + run: docker save dotcms/dotcms-test:1.0.0-SNAPSHOT > /tmp/image.tar + + - id: upload-docker-image + name: Upload Docker Image as Artifact + uses: actions/upload-artifact@v4 + if: ${{ inputs.generate-docker == 'true' }} + with: + name: docker-image + path: /tmp/image.tar + + - id: persist-build-classes + name: Persist Build Classes + if: ${{ inputs.generate-artifacts == 'true' }} + uses: actions/upload-artifact@v4 + with: + name: "build-classes" + path: | + **/target/classes/**/*.class + LICENSE + + - id: delete-built-artifacts-from-cache + name: Delete Built Artifacts From Cache + if: ${{ inputs.generate-artifacts == 'true' && steps.restore-cache-maven.outputs.cache-hit != 'true' }} + shell: bash + run: find ~/.m2 -name \*-SNAPSHOT -type d -exec rm -rf {} + + + - id: save-cache-maven + name: Save Maven Repository Cache + if: ${{ inputs.generate-artifacts == 'true' && steps.restore-cache-maven.outputs.cache-hit != 'true' }} + uses: actions/cache/save@v4 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-mavencore-${{ steps.get-maven-month-key.outputs.month-key }} + + - id: save-cache-node + name: Save Node Binary Cache + if: ${{ inputs.generate-artifacts == 'true' && steps.restore-cache-node.outputs.cache-hit != 'true' }} + uses: actions/cache/save@v4 + with: + path: installs + key: node-binary-${{ hashFiles('core-web/.nvmrc') }} + + - id: save-cache-yarn + name: Save Yarn Cache + if: ${{ inputs.generate-artifacts == 'true' && steps.restore-cache-yarn.outputs.cache-hit != 'true' }} + uses: actions/cache/save@v4 + with: + path: ~/.cache/yarn + key: yarn-${{ hashFiles('**/yarn.lock') }} + + - id: save-cache-sonar + name: Save SonarQube Cache + if: ${{ inputs.cache-sonar == 'true' }} && steps.cache-sonar.outputs.cache-hit != 'true' }} + uses: actions/cache/save@v4 + with: + path: ~/.sonar/cache + key: ${{ runner.os }}-sonar + + # ---------------------------- Generate Reports Artifacts ---------------------------- + - id: generate-build-reports-artifact + name: Generate Build Reports Artifact + uses: actions/upload-artifact@v4 + if: always() + with: + name: "build-reports-${{ inputs.stage-name }}" + path: | + target/build-report.json + LICENSE + retention-days: 2 + + - id: create-test-reports-artifact + name: Create Test Reports Artifact + uses: actions/upload-artifact@v4 + if: ${{ inputs.generates-test-results == 'true' }} + with: + name: "build-reports-test-${{ inputs.stage-name }}" + path: | + **/target/jacoco-report/*.exec + **/target/*-reports/TEST-*.xml \ No newline at end of file diff --git a/.github/actions/prepare-runner/action.yml b/.github/actions/prepare-runner/action.yml new file mode 100644 index 000000000000..7ab66785bd29 --- /dev/null +++ b/.github/actions/prepare-runner/action.yml @@ -0,0 +1,43 @@ +# action.yml +name: 'Prepare Runner' +description: 'Basic steps to prepare the runner' +inputs: + cleanup-runner: + description: 'The runner requires extra disk space' + required: true + default: 'false' + require-graalvm: + description: 'Require GraalVM to be installed' + required: true + default: 'false' + require-java: + description: 'Require java to be installed' + default: 'true' + require-master: + description: 'require the master tag to run this action' + required: true + default: 'false' + java-version: + description: 'The version of Java to install' + required: false + graalvm-version: + description: 'Override the sdkman version of GraalVM to install' + required: false +runs: + using: 'composite' + steps: + - name: Setup master branch locally without switching current branch + shell: bash + if: (github.ref != 'refs/heads/master' && inputs.require-master == 'true') + run: git fetch origin master:master + - name: Cleanup Runner + if: ${{ inputs.cleanup-runner == 'true' }} + uses: ./.github/actions/cleanup-runner + - name: Setup Java + if: ${{ inputs.require-java == 'true' }} + id: setup-java + uses: ./.github/actions/setup-java + with: + java-version: ${{ inputs.java-version }} + graalvm-version: ${{ inputs.graalvm-version }} + require-graalvm: ${{ inputs.require-graalvm }} \ No newline at end of file diff --git a/.github/actions/setup-java/action.yml b/.github/actions/setup-java/action.yml new file mode 100644 index 000000000000..4ceb5a354227 --- /dev/null +++ b/.github/actions/setup-java/action.yml @@ -0,0 +1,112 @@ +name: 'Setup Java' +description: 'Setup Java using SDKMan including optionally setting up GraalVM for native images' +inputs: + java-version: + description: 'Override the java version to install' + required: false + require-graalvm: + description: 'Require GraalVM to be installed' + required: true + default: 'false' + graalvm-version: + description: 'Override the sdkman version of GraalVM to install' + required: false +runs: + using: 'composite' + steps: + - name: 'Setup SDKMan' + id: sdkman-java + shell: bash + run: | + DEFAULT_GRAALVM="21.0.2-graalce" + + if [ ! -f "$HOME/.sdkman/bin/sdkman-init.sh" ]; then + echo "Using sdkman to install SDKMAN" + curl -s "https://get.sdkman.io" | bash + fi + + # Note sdkman-init.sh adds sdk as a function to the current shell + # sdk command is therefore not directly available on subsequent actions + # to use sdkman in a subsequent action you will need to call the following command + # with each script that uses sdk command directly. + # This script otherwise sets the PATH and JAVA_HOME to the selected java so further tasks do not + # need to be aware of sdkman directly + + source "$HOME/.sdkman/bin/sdkman-init.sh" + + REQUESTED_VERSION="${{ inputs.java-version }}" + REQUIRE_GRAALVM="${{ inputs.require-graalvm }}" + GRAALVM_VERSION="${{ inputs.graalvm-version }}" + + # Handle default values for REQUESTED_VERSION and GRAALVM_VERSION + if [ -z "$REQUESTED_VERSION" ]; then + if [ -f .sdkmanrc ]; then + REQUESTED_VERSION=$(awk -F "=" '/^java=/ {print $2}' .sdkmanrc) + echo "Extracted Java version from .sdkmanrc: $REQUESTED_VERSION" + else + echo "No Java version provided and .sdkmanrc file not found." + exit 1 + fi + else + echo "Using provided Java version: $REQUESTED_VERSION" + fi + + if [ -z "$GRAALVM_VERSION" ]; then + GRAALVM_VERSION=${DEFAULT_GRAALVM} + echo "No GraalVM version provided, using default: $GRAALVM_VERSION" + else + echo "Using provided GraalVM version: $GRAALVM_VERSION" + fi + + TEST_HOME=$(sdk home java "$REQUESTED_VERSION" 2>/dev/null) || true + if [ -z "$TEST_HOME" ]; then + echo "Java version $REQUESTED_VERSION is not installed. Installing now..." + echo "y" | sdk install java "$REQUESTED_VERSION" + sdk use java "$REQUESTED_VERSION" + TEST_HOME=$(sdk home java "$REQUESTED_VERSION") + else + echo "Java version $REQUESTED_VERSION is already installed." + sdk use java "$REQUESTED_VERSION" + fi + + + # Ensure JAVA_HOME and path update persist in subsequent steps + echo "JAVA_HOME=$TEST_HOME" >> $GITHUB_ENV + JAVA_BIN_PATH="$HOME/.sdkman/candidates/java/current/bin" + echo "$JAVA_BIN_PATH" >> $GITHUB_PATH + + # Ensure PATH is set correctly for the current script + export JAVA_HOME=$TEST_HOME + export PATH=$JAVA_BIN_PATH:$PATH + + # Set GRAALVM_HOME if the version ends with "-graalce", "-mandrel", or "-graal" + if [[ "$REQUESTED_VERSION" == *"-graalce" || "$REQUESTED_VERSION" == *"-mandrel" || "$REQUESTED_VERSION" == *"-graal" ]]; then + echo "GRAALVM_HOME=$TEST_HOME" >> $GITHUB_ENV + fi + + # Install and set GRAALVM_HOME if required and not already set + if [[ "$REQUIRE_GRAALVM" == "true" ]]; then + if [ -z "$GRAALVM_HOME" ] && [ "$REQUESTED_VERSION" != "$GRAALVM_VERSION" ]; then + echo "Requested version does not match required GraalVM version and GRAALVM_HOME is not set. Installing GraalVM version $GRAALVM_VERSION..." + echo "n" | sdk install java "$GRAALVM_VERSION" + GRAALVM_HOME=$(sdk home java "$GRAALVM_VERSION") + echo "GRAALVM_HOME=$GRAALVM_HOME" >> $GITHUB_ENV + echo "GRAALVM_HOME installed and set to $GRAALVM_HOME" + elif [ -n "$GRAALVM_HOME" ]; then + echo "GRAALVM_HOME is already set to $GRAALVM_HOME, skipping installation of GraalVM." + fi + fi + + CURRENT_JAVA_HOME=$(readlink -f "$HOME/.sdkman/candidates/java/current") + if [ "$CURRENT_JAVA_HOME" != "$TEST_HOME" ]; then + echo "Updating default Java version to $REQUESTED_VERSION" + sdk default java "$REQUESTED_VERSION" + else + echo "Default Java version is already set to $REQUESTED_VERSION" + fi + + # Echo JAVA_HOME, Java version, and path to Java command + echo "JAVA_HOME is set to: $JAVA_HOME" + echo "Path to java command: $(which java)" + echo "Java version:" + java -version \ No newline at end of file diff --git a/.github/workflows/build-test-master.yml b/.github/workflows/build-test-master.yml index 8894acfc484f..1d28afafcdd2 100644 --- a/.github/workflows/build-test-master.yml +++ b/.github/workflows/build-test-master.yml @@ -25,7 +25,7 @@ jobs: reuse-previous-build: ${{ inputs.reuse-previous-build || github.event_name != 'workflow_dispatch' }} build-on-missing-artifacts: ${{ inputs.build-on-missing-artifacts || github.event_name != 'workflow_dispatch' }} build: - name: PR Build + name: Trunk Build needs: [ initialize ] if: needs.initialize.outputs.found_artifacts == 'false' uses: ./.github/workflows/reusable-ci-build.yml @@ -33,7 +33,7 @@ jobs: contents: read packages: write test: - name: PR Test + name: Trunk Test needs: [ initialize,build ] if: always() && !failure() && !cancelled() uses: ./.github/workflows/reusable-ci-test.yml @@ -46,7 +46,7 @@ jobs: contents: read packages: write sonar: - name: PR SonarQube + name: Trunk SonarQube needs: [ initialize,test ] if: always() && !failure() && !cancelled() uses: ./.github/workflows/reusable-sonarqube.yml diff --git a/.github/workflows/build-test-nightly.yml b/.github/workflows/build-test-nightly.yml index fffd079aa8b1..555b6550c5f2 100644 --- a/.github/workflows/build-test-nightly.yml +++ b/.github/workflows/build-test-nightly.yml @@ -56,6 +56,7 @@ jobs: with: buildNativeImage: true branch: ${{ github.ref }} + artifact-run-id: ${{ needs.initialize.outputs.artifact-run-id }} deployment: needs: [ initialize,build-cli,test ] if: always() && !failure() && !cancelled() diff --git a/.github/workflows/build-test-pr.yml b/.github/workflows/build-test-pr.yml index 554292fa5fa6..a39d5f767924 100644 --- a/.github/workflows/build-test-pr.yml +++ b/.github/workflows/build-test-pr.yml @@ -22,6 +22,9 @@ jobs: needs: [ initialize ] if: needs.initialize.outputs.found_artifacts == 'false' uses: ./.github/workflows/reusable-ci-build.yml + with: + core-build: true + run-pr-checks: true permissions: contents: read packages: write diff --git a/.github/workflows/cli-build-artifacts.yml b/.github/workflows/cli-build-artifacts.yml index 8a08e9cd6502..51a3027545c8 100644 --- a/.github/workflows/cli-build-artifacts.yml +++ b/.github/workflows/cli-build-artifacts.yml @@ -8,6 +8,14 @@ on: branch: type: string required: true + artifact-run-id: + default: ${{ github.run_id }} + type: string + version: + description: 'The version of the build' + required: false + type: string + default: '1.0.0-SNAPSHOT' outputs: artifact-id: description: 'The ID of the uploaded artifact' @@ -17,11 +25,9 @@ on: value: ${{ jobs.build.outputs.artifact-url }} env: - JAVA_VERSION: 11 - JAVA_DISTRO: temurin - GRAALVM_VERSION: '22.3.1' BRANCH: ${{ inputs.branch || github.ref_name }} SKIP_TESTS: true + ARTIFACT_RUN_ID: ${{ inputs.artifact-run-id || github.run_id }} defaults: run: @@ -38,9 +44,9 @@ jobs: id: set-os run: | if [[ "${{ inputs.buildNativeImage }}" == "true" ]]; then - RUNNERS='[{ "os": "ubuntu-latest", "label": "Linux" }, { "os": "macos-latest", "label": "macOS-Intel" }, { "os": "macos-13-xlarge", "label": "macOS-Silicon" }]' + RUNNERS='[{ "os": "ubuntu-22.04", "label": "Linux" }, { "os": "macos-13", "label": "macOS-Intel" }, { "os": "macos-14", "label": "macOS-Silicon" }]' else - RUNNERS='[{ "os": "ubuntu-latest", "label": "Linux" }]' + RUNNERS='[{ "os": "ubuntu-22.04", "label": "Linux" }]' fi echo "runners=$RUNNERS" >> $GITHUB_OUTPUT @@ -55,157 +61,19 @@ jobs: outputs: artifact-id: ${{ steps.upload-artifact.outputs.artifact-id }} artifact-url: ${{ steps.upload-artifact.outputs.artifact-url }} - date: ${{ steps.get-date.outputs.date }} steps: - name: 'Checkout' uses: actions/checkout@v4 with: ref: ${{ env.BRANCH }} - - - name: 'Cleanup Ubuntu Runner' - if: ${{ matrix.os == 'ubuntu-latest' }} - uses: ./.github/actions/cleanup-runner - - - name: 'Cleanup MacOS Runner' - if: ${{ contains(matrix.os, 'macos-') }} - uses: ./.github/actions/cleanup-macos-runner - - - name: 'Setup Java' - uses: actions/setup-java@v4 - with: - java-version: ${{ env.JAVA_VERSION }} - distribution: ${{ env.JAVA_DISTRO }} - - # Sets up GRAALVM for native image compilation (Linux/macOS) - # Downloads and installs GRAALVM - # Configures environment variables - - name: 'Set up GRAALVM for ${{ matrix.label }}' - if: ${{ inputs.buildNativeImage == true && matrix.os != 'windows-latest' }} - run: | - if [ "${{ matrix.os }}" == "ubuntu-latest" ]; then - echo "GRAALVM on Linux (AMD64)" - - ARCH=amd64 - PLATFORM=linux - INSTALLATION_PATH=/usr/lib/jvm - - else - if [ "${{ matrix.os }}" == "macos-13-xlarge" ]; then - echo "GRAALVM on Mac (AARCH64)" - ARCH=aarch64 - else - echo "GRAALVM on Mac (AMD64)" - ARCH=amd64 - fi - - PLATFORM=darwin - INSTALLATION_PATH=/Library/Java/JavaVirtualMachines - fi - - echo "PLATFORM=$PLATFORM" - echo "ARCH=$ARCH" - echo "INSTALLATION_PATH=$INSTALLATION_PATH" - - wget https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-${{ env.GRAALVM_VERSION }}/graalvm-ce-java11-${PLATFORM}-${ARCH}-${{ env.GRAALVM_VERSION }}.tar.gz - sudo mkdir -p $INSTALLATION_PATH - tar -xzf graalvm-ce-java11-${PLATFORM}-${ARCH}-${{ env.GRAALVM_VERSION }}.tar.gz - sudo mv graalvm-ce-java11-${{ env.GRAALVM_VERSION }} $INSTALLATION_PATH - - if [ "${{ matrix.os }}" != "ubuntu-latest" ]; then - sudo xattr -r -d com.apple.quarantine /Library/Java/JavaVirtualMachines/graalvm-ce-java11-${{ env.GRAALVM_VERSION }}/Contents/Home - GRAALVM_HOME="${INSTALLATION_PATH}/graalvm-ce-java11-${{ env.GRAALVM_VERSION }}/Contents/Home" - else - GRAALVM_HOME="${INSTALLATION_PATH}/graalvm-ce-java11-${{ env.GRAALVM_VERSION }}" - fi - - echo "GRAALVM_HOME=$GRAALVM_HOME" >> $GITHUB_ENV - echo "JAVA_HOME=$GRAALVM_HOME" >> $GITHUB_ENV - PATH="$GRAALVM_HOME/bin:$PATH" - echo "PATH=$PATH" >> $GITHUB_ENV - gu install native-image - - - name: 'Set up GRAALVM for (Windows)' - if: ${{ inputs.buildNativeImage == true && matrix.os == 'windows-latest' }} - shell: pwsh - run: | - $ARCH="amd64" - $DOWNLOAD_URL="https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-${{ env.GRAALVM_VERSION }}/graalvm-ce-java11-windows-${ARCH}-${{ env.GRAALVM_VERSION }}.zip" - $OUTPUT_PATH="C:\graalvm-ce-java11-windows-${ARCH}-${{ env.GRAALVM_VERSION }}.zip" - $GRAALVM_INSTALLATION_PATH="C:\Program Files (x86)\Java" - - Invoke-WebRequest -Uri $DOWNLOAD_URL -OutFile $OUTPUT_PATH - - if (Test-Path -Path $GRAALVM_INSTALLATION_PATH -PathType Container) { - Write-Host "GRAALVM installation path exists." - } else { - Write-Host "Creating GRAALVM installation path." - New-Item -ItemType Directory -Path $GRAALVM_INSTALLATION_PATH - } - - Expand-Archive -Path $OUTPUT_PATH -DestinationPath $GRAALVM_INSTALLATION_PATH - - $env:JAVA_HOME="${GRAALVM_INSTALLATION_PATH}\graalvm-ce-java11-22.1.0" - $env:Path="${env:Path};${env:JAVA_HOME}\bin;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.38.33130\bin\HostX86\x64" - - echo "JAVA_HOME=${env:JAVA_HOME}" >> "$env:GITHUB_ENV" - echo "Path=${env:Path}" >> "$env:GITHUB_ENV" - - gu.cmd install native-image - - - name: 'Get Date' - id: get-date - run: | - echo "date=$(/bin/date -u "+%Y-%m")" >> $GITHUB_OUTPUT - shell: bash - - - name: 'Cache Maven Repository' - id: cache-maven - uses: actions/cache@v4 + - uses: ./.github/actions/maven-job with: - path: ~/.m2/repository - key: mavencore-${{ steps.get-date.outputs.date }}-${{ github.run_id }} - restore-keys: | - mavencore-${{ steps.get-date.outputs.date }} - - - name: 'Compile source code' - working-directory: ${{ github.workspace }} - run: | - ./mvnw clean install -Dtest.failure.ignore=true -DskipTests=$SKIP_TESTS -am -pl :dotcms-cli - - - name: 'Build uber-jar' - if: ${{ matrix.label == 'Linux' }} - working-directory: ${{ github.workspace }} - run: | - ./mvnw package -DskipTests=$SKIP_TESTS -pl :dotcms-cli - - # Builds a native image of the CLI using GRAALVM (Linux/macOS) - # Runs on a matrix for different operating systems - - name: 'Build Native Image ${{ matrix.label }}' - if: ${{ inputs.buildNativeImage == true && matrix.os != 'windows-latest' }} - working-directory: ${{ github.workspace }} - run: | - ./mvnw package -Pnative -DskipTests=$SKIP_TESTS -pl :dotcms-cli - - # Builds a native image of the CLI using GRAALVM on Windows - # Uses PowerShell for setup and execution - - name: 'Build Native Image (Windows)' - if: ${{ inputs.buildNativeImage == true && matrix.os == 'windows-latest' }} - working-directory: ${{ github.workspace }} - shell: pwsh - run: | - cmd /c 'call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" && .\mvnw.cmd package -Dnative -DskipTests=true -pl :dotcms-cli' - - - name: 'Create distribution' - if: ${{ inputs.buildNativeImage == true }} - working-directory: ${{ github.workspace }} - run: | - ./mvnw -B -ntp -Pdist package -DskipTests=$SKIP_TESTS -pl :dotcms-cli - - - name: 'Distribution tree' - if: ${{ inputs.buildNativeImage == true }} - working-directory: ${{ github.workspace }}/tools/dotcms-cli/ - run: | - ls -ltr cli/target/distributions + stage-name: "Build Native Image ${{ matrix.label }}" + maven-args: "package -Pnative -Pdist -DskipTests=$SKIP_TESTS -pl :dotcms-cli" + native: true + generates-test-results: false + artifacts-from: ${{ env.ARTIFACT_RUN_ID }} + version: ${{ inputs.version }} - name: 'Upload built distribution' id: upload-artifact @@ -213,30 +81,6 @@ jobs: with: name: cli-artifacts-${{ matrix.os }} path: | - ${{ github.workspace }}/tools/dotcms-cli/cli/target/*.jar ${{ github.workspace }}/tools/dotcms-cli/cli/target/distributions/*.zip - ${{ github.workspace }}/tools/dotcms-cli/api-data-model/target/*.jar retention-days: 2 - if-no-files-found: ignore - - - name: Prepare reports archive (if maven failed) - if: failure() - shell: bash - run: find . -name '*-reports' -type d | tar -czf test-reports.tgz -T - - - name: Upload reports Archive (if maven failed) - uses: actions/upload-artifact@v4 - if: failure() - with: - name: test-reports-cli-native-${{ matrix.label }} - path: 'test-reports.tgz' - - name: cli-build - uses: actions/upload-artifact@v4 - if: always() - with: - name: "build-reports-test-cli - native ${{ matrix.label }}" - path: | - tools/dotcms-cli/**/target/failsafe-reports/*.xml - tools/dotcms-cli/**/target/jacoco-report/*.exec - target/build-report.json - LICENSE - retention-days: 2 \ No newline at end of file + if-no-files-found: ignore \ No newline at end of file diff --git a/.github/workflows/cli-release-process.yml b/.github/workflows/cli-release-process.yml index ddf1a6190ddd..563a1f3b6f3c 100644 --- a/.github/workflows/cli-release-process.yml +++ b/.github/workflows/cli-release-process.yml @@ -1,4 +1,5 @@ name: dotCLI Release +run-name: dotCLI Release ${{ inputs.version }} - dry-run=${{ inputs.dry-run }} on: release: types: [created] @@ -23,16 +24,18 @@ defaults: shell: bash env: - JAVA_VERSION: 11 - JAVA_DISTRO: temurin - GRAALVM_VERSION: '22.3.1' + ARTIFACT_RUN_ID: ${{ github.run_id }} MVN_PACKAGE_TYPE: 'uber-jar' NPM_PACKAGE_SCOPE: '@dotcms' NPM_PACKAGE_NAME: 'dotcli' MVN_PACKAGE_NAME: 'dotcms-cli' NODE_VERSION: 19 - jobs: + initialize: + name: Initialize + uses: ./.github/workflows/reusable-initialize.yml + + precheck: if: ${{ ( github.event_name == 'release' && !contains(github.event.release.tag_name, 'LTS')) || github.event_name == 'workflow_dispatch' }} name: 'Pre-check' @@ -41,7 +44,6 @@ jobs: RELEASE_VERSION: ${{ steps.version.outputs.RELEASE_VERSION }} HEAD: ${{ steps.version.outputs.HEAD }} AUXILIARY_BRANCH: ${{ steps.version.outputs.AUXILIARY_BRANCH }} - DATE: ${{ steps.get-date.outputs.DATE }} steps: - name: 'Log GitHub context' env: @@ -64,34 +66,13 @@ jobs: - name: 'Checkout' uses: actions/checkout@v4 - - name: 'Setup Java' - uses: actions/setup-java@v4 - with: - java-version: ${{ env.JAVA_VERSION }} - distribution: ${{ env.JAVA_DISTRO }} - - - uses: ./.github/actions/cleanup-runner - - - name: 'Get Date' - id: get-date - run: | - echo "DATE=$(/bin/date -u "+%Y-%m")" >> $GITHUB_OUTPUT - shell: bash - - - name: 'Restore Maven Repository' - id: cache-maven - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: maven-${{ steps.get-date.outputs.DATE }}-${{ github.run_id }} - - name: 'Setup git config' run: | git config user.name "${{ secrets.CI_MACHINE_USER }}" git config user.email "dotCMS-Machine-User@dotcms.com" - # Sets the release version and the next version - # Creates an auxiliary branch for versioning updates + # Sets the release version and the next version + # Creates an auxiliary branch for versioning updates - name: 'Set release version' id: version run: | @@ -117,190 +98,41 @@ jobs: echo "HEAD=$HEAD" >> "$GITHUB_OUTPUT" echo "AUXILIARY_BRANCH=$AUXILIARY_BRANCH" >> "$GITHUB_OUTPUT" - get-runners: - needs: [ precheck ] - name: 'Get runners' - runs-on: ubuntu-latest - outputs: - matrix: ${{ steps.set-matrix.outputs.matrix }} - steps: - - id: set-matrix - run: | - RUNNERS='[{ "os": "ubuntu-latest", "label": "Linux", "platform": "linux-x86_64" }, { "os": "macos-latest", "label": "macOS-Intel", "platform": "osx-x86_64" }, { "os": "macos-13-xlarge", "label": "macOS-Silicon", "platform": "osx-aarch_64" }]' - echo "matrix=$RUNNERS" >> $GITHUB_OUTPUT - - # Build native executable per runner build: - needs: [ precheck, get-runners ] - name: 'Build native image on ${{ matrix.label }}' - strategy: - fail-fast: true - matrix: - include: ${{ fromJSON(needs.get-runners.outputs.matrix) }} - - runs-on: ${{ matrix.os }} - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - with: - ref: ${{ needs.precheck.outputs.AUXILIARY_BRANCH }} - - - name: 'Cleanup Runner' - if: ${{ matrix.os == 'ubuntu-latest' }} - uses: ./.github/actions/cleanup-runner - - - name: 'Cleanup macOS Runner' - if: ${{ contains(matrix.os, 'macos-') }} - uses: ./.github/actions/cleanup-macos-runner - - # Sets up GraalVM for native image compilation (Linux/macOS) - # Downloads and installs GraalVM - # Configures environment variables - - name: 'Set up GRAALVM for ${{ matrix.label }}' - if: ${{ matrix.os != 'windows-latest' }} - run: | - if [ "${{ matrix.os }}" == "ubuntu-latest" ]; then - echo "GraalVM on Linux (AMD64)" - - ARCH=amd64 - PLATFORM=linux - INSTALLATION_PATH=/usr/lib/jvm - - else - if [ "${{ matrix.os }}" == "macos-13-xlarge" ]; then - echo "GraalVM on Mac (AARCH64)" - ARCH=aarch64 - else - echo "GraalVM on Mac (AMD64)" - ARCH=amd64 - fi - - PLATFORM=darwin - INSTALLATION_PATH=/Library/Java/JavaVirtualMachines - fi - - echo "PLATFORM=$PLATFORM" - echo "ARCH=$ARCH" - echo "INSTALLATION_PATH=$INSTALLATION_PATH" - - wget https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-${{ env.GRAALVM_VERSION }}/graalvm-ce-java11-${PLATFORM}-${ARCH}-${{ env.GRAALVM_VERSION }}.tar.gz - sudo mkdir -p $INSTALLATION_PATH - tar -xzf graalvm-ce-java11-${PLATFORM}-${ARCH}-${{ env.GRAALVM_VERSION }}.tar.gz - sudo mv graalvm-ce-java11-${{ env.GRAALVM_VERSION }} $INSTALLATION_PATH - - if [ "${{ matrix.os }}" != "ubuntu-latest" ]; then - sudo xattr -r -d com.apple.quarantine /Library/Java/JavaVirtualMachines/graalvm-ce-java11-${{ env.GRAALVM_VERSION }}/Contents/Home - GRAALVM_HOME="${INSTALLATION_PATH}/graalvm-ce-java11-${{ env.GRAALVM_VERSION }}/Contents/Home" - else - GRAALVM_HOME="${INSTALLATION_PATH}/graalvm-ce-java11-${{ env.GRAALVM_VERSION }}" - fi - - echo "GRAALVM_HOME=$GRAALVM_HOME" >> $GITHUB_ENV - echo "JAVA_HOME=$GRAALVM_HOME" >> $GITHUB_ENV - PATH="$GRAALVM_HOME/bin:$PATH" - echo "PATH=$PATH" >> $GITHUB_ENV - gu install native-image - - - name: 'Set up GraalVM for (Windows)' - if: ${{ matrix.os == 'windows-latest' }} - shell: pwsh - run: | - $ARCH="amd64" - $DOWNLOAD_URL="https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-${{ env.GRAALVM_VERSION }}/graalvm-ce-java11-windows-${ARCH}-${{ env.GRAALVM_VERSION }}.zip" - $OUTPUT_PATH="C:\graalvm-ce-java11-windows-${ARCH}-${{ env.GRAALVM_VERSION }}.zip" - $GRAALVM_INSTALLATION_PATH="C:\Program Files (x86)\Java" - - Invoke-WebRequest -Uri $DOWNLOAD_URL -OutFile $OUTPUT_PATH - - if (Test-Path -Path $GRAALVM_INSTALLATION_PATH -PathType Container) { - Write-Host "GRAALVM installation path exists." - } else { - Write-Host "Creating GRAALVM installation path." - New-Item -ItemType Directory -Path $GRAALVM_INSTALLATION_PATH - } - - Expand-Archive -Path $OUTPUT_PATH -DestinationPath $GRAALVM_INSTALLATION_PATH - - $env:JAVA_HOME="${GRAALVM_INSTALLATION_PATH}\graalvm-ce-java11-22.1.0" - $env:Path="${env:Path};${env:JAVA_HOME}\bin;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build;C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.38.33130\bin\HostX86\x64" - - echo "JAVA_HOME=${env:JAVA_HOME}" >> "$env:GITHUB_ENV" - echo "Path=${env:Path}" >> "$env:GITHUB_ENV" - - gu.cmd install native-image - - - name: 'Cache Maven packages' - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: maven-${{ needs.precheck.outputs.DATE }}-${{ github.run_id }} - - - name: 'Prepare dotCMS license' - env: - DOTCMS_LICENSE_KEY: ${{ secrets.DOTCMS_LICENSE }} - run: | - DOTCMS_LICENSE_PATH=~/.dotcms/license - mkdir -p ${DOTCMS_LICENSE_PATH} - echo "${DOTCMS_LICENSE_KEY}" > ${DOTCMS_LICENSE_PATH}/license.dat - echo "DOTCMS_LICENSE_FILE=${DOTCMS_LICENSE_PATH}/license.dat" >> "$GITHUB_ENV" - - - name: 'Compile source code' - working-directory: ${{ github.workspace }} - run: | - ./mvnw clean install -Dtest.failure.ignore=true -DskipTests=true -am -pl :dotcms-cli - - - name: 'Build uber-jar' - working-directory: ${{ github.workspace }} - run: | - ./mvnw package -Dquarkus.package.type=${{ env.MVN_PACKAGE_TYPE }} -DskipTests=true -pl :dotcms-cli - - # Builds a native image of the CLI using GraalVM (Linux/macOS) - # Runs on a matrix for different operating systems - - name: 'Build Native Image ${{ matrix.label }}' - if: ${{ matrix.os != 'windows-latest' }} - working-directory: ${{ github.workspace }} - run: | - ./mvnw package -Pnative -DskipTests=true -pl :dotcms-cli - - # Builds a native image of the CLI using GraalVM on Windows - # Uses PowerShell for setup and execution - - name: 'Build Native Image (Windows)' - if: ${{ matrix.os == 'windows-latest' }} - working-directory: ${{ github.workspace }} - shell: pwsh - run: | - cmd /c 'call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" && .\mvnw.cmd package -Dnative -DskipTests=true -pl :dotcms-cli' - - - name: 'Create distribution' - working-directory: ${{ github.workspace }} - run: | - ./mvnw -B -ntp -Pdist package -DskipTests=true -pl :dotcms-cli - - - name: 'Distribution tree' - working-directory: ${{ github.workspace }}/tools/dotcms-cli/ - run: | - ls -ltr cli/target/distributions - - - name: 'Upload build artifact' - uses: actions/upload-artifact@v4 - with: - name: artifacts-${{ matrix.platform }} - path: | - ${{ github.workspace }}/tools/dotcms-cli/cli/target/*-runner.jar - ${{ github.workspace }}/tools/dotcms-cli/cli/target/distributions/*.zip - ${{ github.workspace }}/tools/dotcms-cli/cli/target/distributions/*.tar.gz + name: Release Build + needs: [ initialize, precheck ] + if: needs.initialize.outputs.found_artifacts == 'false' + uses: ./.github/workflows/reusable-ci-build.yml + with: + core-build: true + ref: ${{ needs.precheck.outputs.AUXILIARY_BRANCH }} + validate: false + version: ${{ needs.precheck.outputs.RELEASE_VERSION }} + generate-docker: false + + permissions: + contents: read + packages: write + + build-cli: + name: Release CLI Build + needs: [ initialize, precheck, build ] + if: always() && !failure() && !cancelled() + uses: ./.github/workflows/cli-build-artifacts.yml + with: + buildNativeImage: true + artifact-run-id: ${{ needs.initialize.outputs.artifact-run-id }} + version: ${{ needs.precheck.outputs.RELEASE_VERSION }} + branch: ${{ needs.precheck.outputs.AUXILIARY_BRANCH }} release: - needs: [ precheck, build ] + needs: [ precheck, build-cli ] runs-on: ubuntu-latest steps: - name: 'Check out repository' uses: actions/checkout@v4 with: ref: ${{ needs.precheck.outputs.AUXILIARY_BRANCH }} - - - uses: ./.github/actions/cleanup-runner - - name: 'Create artifacts directory' run: | mkdir -p ${{ github.workspace }}/artifacts @@ -310,43 +142,24 @@ jobs: uses: actions/download-artifact@v4 with: path: ${{ github.workspace }}/artifacts - pattern: artifacts-* - - - name: 'List artifacts' - run: | - ls -R - - - name: 'Set up Java' - uses: actions/setup-java@v4 - with: - java-version: ${{ env.JAVA_VERSION }} - distribution: ${{ env.JAVA_DISTRO }} - - - name: 'Cache Maven packages' - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: maven-${{ needs.precheck.outputs.DATE }}-${{ github.run_id }} - - # Creates automated releases using JReleaser - # Generates builds for different platforms - # Signs artifacts - # Publishes to artifact repositories - - name: 'JReleaser' + pattern: cli-artifacts-* + - uses: ./.github/actions/maven-job env: JRELEASER_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} JRELEASER_PROJECT_VERSION: ${{ needs.precheck.outputs.RELEASE_VERSION }} JRELEASER_ARTIFACTORY_USERNAME: ${{ secrets.EE_REPO_USERNAME }} JRELEASER_ARTIFACTORY_PASSWORD: ${{ secrets.EE_REPO_PASSWORD }} JRELEASER_DRY_RUN: ${{ github.event.inputs.dry-run || 'false' }} - working-directory: ${{ github.workspace }} - run: | - tools/dotcms-cli/mvnw -B -Prelease validate -DartifactsDir=artifacts -Djreleaser.git.root.search=true -pl :dotcms-cli-parent -Dmaven.plugin.validation=VERBOSE + with: + stage-name: "JReleaser" + maven-args: "-Prelease validate -DartifactsDir=artifacts -Dm2Dir=$HOME/.m2/repository -Djreleaser.git.root.search=true -pl :dotcms-cli-parent -Dmaven.plugin.validation=VERBOSE" + artifacts-from: ${{ env.ARTIFACT_RUN_ID }} + version: ${{ needs.precheck.outputs.RELEASE_VERSION }} publish-npm-package: name: "Publish NPM Package" if: success() # Run only if explicitly indicated and successful - needs: [ precheck, build, release ] + needs: [ precheck, build, build-cli, release ] runs-on: ubuntu-latest steps: - name: 'Checkout code' @@ -368,7 +181,7 @@ jobs: uses: actions/download-artifact@v4 with: path: ${{ github.workspace }}/artifacts - pattern: artifacts-* + pattern: cli-artifacts-* merge-multiple: true # Determines the NPM package version and tag @@ -447,7 +260,7 @@ jobs: echo "::group::NPM Package setup" echo "Adding bin folder with all the binaries" mkdir -p bin - find ${{ github.workspace }}/artifacts/distributions/ -name "*.zip" -exec unzip -d bin {} \; + find ${{ github.workspace }}/artifacts/ -name "*.zip" -exec unzip -d bin {} \; echo "Adding wrapper script" mv src/postinstall.js.seed src/postinstall.js @@ -490,7 +303,7 @@ jobs: clean-up: name: "Clean Up" if: ${{ needs.precheck.outputs.AUXILIARY_BRANCH != '' }} - needs: [ precheck, build, release, publish-npm-package ] + needs: [ precheck, build, build-cli, release, publish-npm-package ] runs-on: ubuntu-latest steps: - name: Checkout Repository diff --git a/.github/workflows/reusable-ci-build.yml b/.github/workflows/reusable-ci-build.yml index 81bd25020029..a43492cd1a63 100644 --- a/.github/workflows/reusable-ci-build.yml +++ b/.github/workflows/reusable-ci-build.yml @@ -3,15 +3,32 @@ on: workflow_call: inputs: core-build: + description: "Run core build" + type: boolean + default: true + run-pr-checks: + description: "Run PR checks" + type: boolean + default: false + ref: + description: "Branch or tag ref" + required: false + default: '' + type: string + validate: + description: "Run validation" + type: boolean + default: false + version: + description: 'The version of the build' + required: false + type: string + default: '1.0.0-SNAPSHOT' + generate-docker: + description: 'Generate docker artifact' + required: false type: boolean default: true -env: - JVM_TEST_MAVEN_OPTS: "-e -B --no-transfer-progress -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn" - DOCKER_PLATFORMS: "linux/amd64,linux/arm64" - REGISTRY: ghcr.io - DOCKER_IMAGE: dotcms/dotcms_test - DOCKER_TAG: run-${{ github.run_id }} - jobs: # # Initial JDK 11 Build @@ -22,99 +39,59 @@ jobs: name: "Initial Artifact Build" runs-on: ubuntu-20.04 if: inputs.core-build == true - env: - DOCKER_BUILD_CONTEXT: /home/runner/work/_temp/core-build permissions: contents: read packages: write steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 + if: inputs.ref == '' with: fetch-depth: 0 - - name: Setup master branch locally without switching current branch - if: github.ref != 'refs/heads/master' - run: git fetch origin master:master - - uses: ./.github/actions/cleanup-runner - - name: Set up JDK 11 - uses: actions/setup-java@v4 - with: - java-version: '11' - distribution: 'temurin' - - name: Get Date - id: get-date - run: | - echo "date=$(/bin/date -u "+%Y-%m")" >> $GITHUB_OUTPUT - shell: bash - - name: Cache Maven Repository - id: cache-maven - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: mavencore-${{ steps.get-date.outputs.date }}-${{ github.run_id }} - restore-keys: | - mavencore-${{ steps.get-date.outputs.date }} - - name: Cache Node Binary - id: cache-node-binary - uses: actions/cache@v4 - with: - path: | - installs - key: node-binary-${{ hashFiles('core-web/.nvmrc') }} - - name: Cache yarn - id: cache-yarn - uses: actions/cache@v4 + - name: Checkout code with ref ${{ inputs.ref }} + if: inputs.ref != '' + uses: actions/checkout@v4 with: - path: | - ~/.cache/yarn - # if specific cache does not exist then can base upon latest version - key: yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: yarn- - - name: Lint Checks - shell: bash + ref: ${{ inputs.ref }} + fetch-depth: 0 + + - name: Check if .mvn/maven.config is in the PR commit + if: inputs.run-pr-checks run: | - ./mvnw $JVM_TEST_MAVEN_OPTS -Pvalidate --fail-at-end -Dgithub.event.name=${{ github.event_name }} --file pom.xml - - name: Maven Build No Test - shell: bash + if git diff --name-only origin/main...HEAD | grep -q '^\.mvn/maven.config$'; then + echo "Error: .mvn/maven.config should not be modified in PR commits. This should only be set on release branches." + exit 1 + else + echo ".mvn/maven.config is not modified in this PR." + fi + + - name: Set up validate profile + id: setup-validate-profile run: | - echo "Creating $DOCKER_BUILD_CONTEXT" - mkdir -p $DOCKER_BUILD_CONTEXT - ./mvnw -Dprod=true $JVM_TEST_MAVEN_OPTS -Dcoreit.test.skip=true -Dpostman.test.skip=true -Ddocker.buildArchiveOnly=$DOCKER_BUILD_CONTEXT -Ddotcms.image.name=${DOCKER_IMAGE}:${DOCKER_TAG} --show-version -DskipTests=true -DskipITs=true clean install --file pom.xml - - name: Persist Maven Repo - uses: actions/upload-artifact@v4 - with: - name: maven-repo - path: ~/.m2/repository - - name: Delete Local Artifacts From Cache - shell: bash - run: find ~/.m2 -name \*-SNAPSHOT -type d -exec rm -rf {} + - - name: Persist Docker Build Context - uses: actions/upload-artifact@v4 - with: - name: docker-build-context - path: ${{ env.DOCKER_BUILD_CONTEXT }}/docker-build.tar - - name: Save Docker image to a tar file - run: docker save ${{ env.DOCKER_IMAGE }}:${{ env.DOCKER_TAG }} > image.tar + if [ "${{ inputs.validate }}" == "true" ]; then + echo "VALIDATE_PROFILE=-Pvalidate" >> $GITHUB_ENV + else + echo "VALIDATE_PROFILE=" >> $GITHUB_ENV + fi - - name: Upload Docker image as artifact - uses: actions/upload-artifact@v4 + - uses: ./.github/actions/maven-job with: - name: docker-image - path: image.tar - - name: core-build-report - uses: actions/upload-artifact@v4 - if: always() - with: - name: "build-reports-Initial Artifact Build" - path: | - target/build-report.json - LICENSE - retention-days: 2 - - name: build-classes # required for sonarqube - uses: actions/upload-artifact@v4 - if: always() - with: - name: "build-classes-Initial Artifact Build" - path: | - **/target/classes/**/*.class - LICENSE - retention-days: 2 \ No newline at end of file + stage-name: "Initial Artifact Build" + maven-args: "clean install ${{ env.VALIDATE_PROFILE }} -DskipTests=true -Dgithub.event.name=${{ github.event_name }}" + generate-artifacts: true + require-master: ${{ inputs.version == '1.0.0-SNAPSHOT' }} + github-token: ${{ secrets.GITHUB_TOKEN }} + cleanup-runner: true + version: ${{ inputs.version }} + generate-docker: ${{ inputs.generate-docker }} + + - name: Check for changes to source during build + if: inputs.run-pr-checks + run: | + if [[ -n "$(git status --porcelain)" ]]; then + echo "Error: There are uncommitted changes in the working directory. These may have been modified by the build process. Go back and run a full build before committing changes, or add these files to .gitignore if not required to be stored in the source to ensure the build is clean." + git status --porcelain + exit 1 + else + echo "No uncommitted changes found." + fi \ No newline at end of file diff --git a/.github/workflows/reusable-ci-test.yml b/.github/workflows/reusable-ci-test.yml index 4cfac688a8fa..6afc84dbe819 100644 --- a/.github/workflows/reusable-ci-test.yml +++ b/.github/workflows/reusable-ci-test.yml @@ -1,4 +1,4 @@ -name: Reusable CI Build Test +name: Reusable CI Test on: workflow_call: inputs: @@ -32,13 +32,7 @@ on: DOTCMS_LICENSE: required: true env: - JVM_TEST_MAVEN_OPTS: "-e -B --no-transfer-progress -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn" - DOCKER_PLATFORMS: "linux/amd64,linux/arm64" - REGISTRY: ghcr.io - DOCKER_IMAGE: dotcms/dotcms_test - DOCKER_TAG: run-${{ inputs.artifact-run-id || github.run_id }} ARTIFACT_RUN_ID: ${{ inputs.artifact-run-id || github.run_id }} - jobs: # # Run all JVM Unit Tests in parallel with other tests @@ -50,125 +44,41 @@ jobs: timeout-minutes: 240 env: MAVEN_OPTS: -Xmx2048m - strategy: - fail-fast: false - matrix: - java: [ { name: "11", java-version: 11, distribution: 'temurin', maven_args: "" } ] steps: - - uses: actions/checkout@v4 - - name: Set up JDK ${{ matrix.java.name }} - uses: actions/setup-java@v4 + - name: Checkout code + uses: actions/checkout@v4 with: - java-version: ${{ matrix.java.java-version }} - distribution: ${{ matrix.java.distribution }} - - name: Get Date - id: get-date - run: | - echo "date=$(/bin/date -u "+%Y-%m")" >> $GITHUB_OUTPUT - shell: bash - - name: Download Maven Repo - uses: actions/download-artifact@v4 + fetch-depth: 0 + - uses: ./.github/actions/maven-job with: - run-id: ${{ env.ARTIFACT_RUN_ID }} + stage-name: "JVM Tests" + maven-args: "-Pcoverage -Dprod test -pl :dotcms-core" + cleanup-runner: true + generates-test-results: true github-token: ${{ secrets.GITHUB_TOKEN }} - name: maven-repo - path: ~/.m2/repository - - name: Build - # exclude core web we aare testing that separately - run: eval ./mvnw -Pcoverage -Dprod $JVM_TEST_MAVEN_OPTS test -pl \!:dotcms-core-web ${{ matrix.java.maven_args}} - - name: Prepare reports archive (if maven failed) - if: failure() - shell: bash - run: find . -name '*-reports' -type d | tar -czf test-reports.tgz -T - - - name: Upload reports Archive (if maven failed) - uses: actions/upload-artifact@v4 - if: failure() - with: - name: test-reports-linux-jvm${{matrix.java.name}} - path: 'test-reports.tgz' - - name: core-maven-unit-tests - uses: actions/upload-artifact@v4 - if: always() - with: - name: "build-reports-test-JVM Tests - JDK ${{matrix.java.name}}" - path: | - dotCMS/target/*-reports/TEST-*.xml - dotCMS/target/jacoco-report/*.exec - target/build-report.json - LICENSE - retention-days: 2 - + artifacts-from: ${{ env.ARTIFACT_RUN_ID }} linux-cli-tests: - name: CLI Tests - JDK ${{matrix.java.name}} + name: CLI Tests runs-on: ubuntu-20.04 if: inputs.cli || inputs.run-all-tests timeout-minutes: 240 env: MAVEN_OPTS: -Xmx2048m - strategy: - fail-fast: true - matrix: - java: [ { name: "11", java-version: 11, distribution: 'temurin', maven_args: "" } ] steps: - - uses: actions/checkout@v4 - - name: Set up JDK ${{ matrix.java.name }} - uses: actions/setup-java@v4 - with: - java-version: ${{ matrix.java.java-version }} - distribution: ${{ matrix.java.distribution }} - - name: Download Docker image artifact - uses: actions/download-artifact@v4 + - name: Checkout code + uses: actions/checkout@v4 with: - run-id: ${{ env.ARTIFACT_RUN_ID }} - github-token: ${{ secrets.GITHUB_TOKEN }} - name: docker-image - path: /tmp/docker-image - - name: Load Docker image from tar file - run: docker load < /tmp/docker-image/image.tar - - name: Get Date - id: get-date - run: | - echo "date=$(/bin/date -u "+%Y-%m")" >> $GITHUB_OUTPUT - shell: bash - - name: Download Maven Repo - uses: actions/download-artifact@v4 + fetch-depth: 0 + - uses: ./.github/actions/maven-job with: - run-id: ${{ env.ARTIFACT_RUN_ID }} + stage-name: "CLI Tests" + maven-args: "-pl :dotcms-api-data-model,:dotcms-cli verify" + generates-test-results: true + cleanup-runner: true + dotcms-license: ${{ secrets.DOTCMS_LICENSE }} + needs-docker-image: true github-token: ${{ secrets.GITHUB_TOKEN }} - name: maven-repo - path: ~/.m2/repository - - id: prepare-license - name: Prepare license - env: - DOTCMS_LICENSE_KEY: ${{ secrets.DOTCMS_LICENSE }} - run: | - DOTCMS_LICENSE_PATH=~/.dotcms/license - mkdir -p ${DOTCMS_LICENSE_PATH} - echo "${DOTCMS_LICENSE_KEY}" > ${DOTCMS_LICENSE_PATH}/license.dat - echo "DOTCMS_LICENSE_FILE=${DOTCMS_LICENSE_PATH}/license.dat" >> "$GITHUB_ENV" - - name: Build - run: eval ./mvnw -Dprod $JVM_TEST_MAVEN_OPTS -Dtestcontainers.docker.image=${DOCKER_IMAGE}:${DOCKER_TAG} -pl :dotcms-api-data-model,:dotcms-cli verify ${{ matrix.java.maven_args}} - - name: Prepare reports archive (if maven failed) - if: failure() - shell: bash - run: find . -name '*-reports' -type d | tar -czf test-reports.tgz -T - - - name: Upload reports Archive (if maven failed) - uses: actions/upload-artifact@v4 - if: failure() - with: - name: test-reports-cli-jvm${{matrix.java.name}} - path: 'test-reports.tgz' - - name: cli-tests - uses: actions/upload-artifact@v4 - if: always() - with: - name: "build-reports-test-cli - JDK ${{matrix.java.name}}" - path: | - tools/dotcms-cli/**/target/failsafe-reports/*.xml - tools/dotcms-cli/**/target/jacoco-report/*.exec - target/build-report.json - LICENSE - retention-days: 2 + artifacts-from: ${{ env.ARTIFACT_RUN_ID }} # # Run Frontend Tests @@ -181,69 +91,24 @@ jobs: env: MAVEN_OPTS: -Xmx2048m steps: - - uses: actions/checkout@v4 - - name: Set up JDK 11 - uses: actions/setup-java@v4 + - name: Checkout code + uses: actions/checkout@v4 with: - java-version: 11 - distribution: 'temurin' - - name: Get Date - id: get-date - run: | - echo "date=$(/bin/date -u "+%Y-%m")" >> $GITHUB_OUTPUT - shell: bash - - name: Download Maven Repo - uses: actions/download-artifact@v4 + fetch-depth: 0 + - uses: ./.github/actions/maven-job with: - run-id: ${{ env.ARTIFACT_RUN_ID }} + stage-name: "Frontend Tests" + maven-args: "-pl :dotcms-core-web test" + generates-test-results: true + cleanup-runner: true github-token: ${{ secrets.GITHUB_TOKEN }} - name: maven-repo - path: ~/.m2/repository - continue-on-error: true - - name: Restore Node Binary - id: cache-node-binary - uses: actions/cache/restore@v4 - with: - path: | - installs - key: node-binary-${{ hashFiles('core-web/.nvmrc') }} - - name: Cache yarn - id: cache-yarn - uses: actions/cache@v4 - with: - path: | - ~/.cache/yarn - # if specific cache does not exist then can base upon latest version - key: yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: yarn- - - name: Build # expect node cache to exist from - shell: bash - run: eval ./mvnw -Dprod $JVM_TEST_MAVEN_OPTS -pl :dotcms-core-web test - - name: Prepare failure archive (if maven failed) - if: failure() - shell: bash - run: find . -name 'surefire-reports' -type d | tar -czf test-reports.tgz -T - - - name: Upload failure Archive (if maven failed) - uses: actions/upload-artifact@v4 - if: failure() - with: - name: test-reports-frontend - path: 'test-reports.tgz' - - name: frontend-unit-tests - uses: actions/upload-artifact@v4 - if: always() - with: - name: "build-reports-test-Frontend unit tests" - path: | - core-web/target/*-reports/**/TEST-*.xml - target/build-report.json - LICENSE - retention-days: 2 + artifacts-from: ${{ env.ARTIFACT_RUN_ID }} + # # Run Legacy Integration test suite batches # linux-integration-tests: - name: JVM IT Tests - JDK ${{matrix.java.name}} ${{matrix.suites.name}} + name: JVM IT Tests ${{matrix.suites.name}} runs-on: ubuntu-20.04 # Skip master in forks if: inputs.integration || inputs.run-all-tests @@ -253,56 +118,27 @@ jobs: strategy: fail-fast: false matrix: - java: [ { name: "11", java-version: 11, distribution: 'temurin', maven_args: "" } ] suites: - - { name: "MainSuite 1a", pathName: "mainsuite1a", maven_args: '-Dit.test=MainSuite1a -Dit.test.forkcount=1' } - - { name: "MainSuite 1b", pathName: "mainsuite1b", maven_args: '-Dit.test=MainSuite1b -Dit.test.forkcount=1' } - - { name: "MainSuite 2a", pathName: "mainsuite2a", maven_args: '-Dit.test=MainSuite2a -Dit.test.forkcount=1' } - - { name: "MainSuite 2b", pathName: "mainsuite2b", maven_args: '-Dit.test=MainSuite2b -Dit.test.forkcount=1' } + - { name: "MainSuite 1a", pathName: "mainsuite1a", maven_args: '-Dit.test=MainSuite1a' } + - { name: "MainSuite 1b", pathName: "mainsuite1b", maven_args: '-Dit.test=MainSuite1b' } + - { name: "MainSuite 2a", pathName: "mainsuite2a", maven_args: '-Dit.test=MainSuite2a' } + - { name: "MainSuite 2b", pathName: "mainsuite2b", maven_args: '-Dit.test=MainSuite2b' } steps: - - uses: actions/checkout@v4 - - name: Set up IT Tests ${{ matrix.java.name }} ${{ matrix.suites.name }} - uses: actions/setup-java@v4 + - name: Checkout code + uses: actions/checkout@v4 with: - java-version: ${{ matrix.java.java-version }} - distribution: ${{ matrix.java.distribution }} - - name: Get Date - id: get-date - run: | - echo "date=$(/bin/date -u "+%Y-%m")" >> $GITHUB_OUTPUT - shell: bash - - name: Download Maven Repo - uses: actions/download-artifact@v4 + fetch-depth: 0 + - uses: ./.github/actions/maven-job with: - run-id: ${{ env.ARTIFACT_RUN_ID }} + stage-name: "IT Tests ${{ matrix.suites.name }}" + maven-args: "-Dit.test.forkcount=1 -Pcoverage verify -pl :dotcms-integration -Dcoreit.test.skip=false ${{ matrix.suites.maven_args}}" + generates-test-results: true + cleanup-runner: true + dotcms-license: ${{ secrets.DOTCMS_LICENSE }} + requires-node: false github-token: ${{ secrets.GITHUB_TOKEN }} - name: maven-repo - path: ~/.m2/repository - - name: Build - env: - DOT_DOTCMS_LICENSE: ${{ secrets.DOTCMS_LICENSE }} - run: eval ./mvnw -Pcoverage -Dprod $JVM_TEST_MAVEN_OPTS verify -pl :dotcms-integration -Dcoreit.test.skip=false ${{ matrix.suites.maven_args}} ${{ matrix.java.maven_args}} - - name: Prepare reports archive (if maven failed) - if: failure() - shell: bash - run: find . -name '*-reports' -type d | tar -czf test-reports.tgz -T - - - name: Upload failure Archive (if maven failed) - uses: actions/upload-artifact@v4 - if: failure() - with: - name: test-reports-linux-jvm${{matrix.java.name}}-${{matrix.suites.pathName}} - path: 'test-reports.tgz' - - name: failsafe-it-tests # Uploads will be merged with same name - uses: actions/upload-artifact@v4 - if: always() - with: - name: "build-reports-test-IT Tests - JDK ${{matrix.java.name}} - ${{matrix.suites.name}}" - path: | - dotcms-integration/target/failsafe-reports/*.xml - dotcms-integration/target/jacoco-report/*.exec - target/build-report.json - LICENSE - retention-days: 2 + artifacts-from: ${{ env.ARTIFACT_RUN_ID }} + linux-postman-tests: name: Run Postman Tests - ${{matrix.collection_group}} @@ -313,79 +149,17 @@ jobs: matrix: collection_group: [ 'category-content', 'container', 'experiment', 'graphql', 'page', 'pp', 'template', 'workflow', 'default-split', 'default' ] steps: - - id: fetch-core - name: Fetch Core Repo + - name: Checkout code uses: actions/checkout@v4 - - uses: ./.github/actions/cleanup-runner - - name: Download Maven Repo - uses: actions/download-artifact@v4 with: - run-id: ${{ env.ARTIFACT_RUN_ID }} - github-token: ${{ secrets.GITHUB_TOKEN }} - name: maven-repo - path: ~/.m2/repository - - name: Download Docker image artifact - uses: actions/download-artifact@v4 + fetch-depth: 0 + - uses: ./.github/actions/maven-job with: - run-id: ${{ env.ARTIFACT_RUN_ID }} + stage-name: "Postman ${{ matrix.collection_group }}" + maven-args: "-Pcoverage verify -pl :dotcms-postman -Dpostman.test.skip=false -Dpostman.collections=${{ matrix.collection_group }}" + generates-test-results: true + dotcms-license: ${{ secrets.DOTCMS_LICENSE }} + requires-node: false + needs-docker-image: true github-token: ${{ secrets.GITHUB_TOKEN }} - name: docker-image - path: /tmp/docker-image - - name: Load Docker image from tar file - run: docker load < /tmp/docker-image/image.tar - - - name: Cache Node Binary - id: cache-node-binary - uses: actions/cache@v4 - with: - path: | - installs - key: node-binary-${{ hashFiles('core-web/.nvmrc') }} - - name: Cache yarn - id: cache-yarn - uses: actions/cache@v4 - with: - path: | - ~/.cache/yarn - # if specific cache does not exist then can base upon latest version - key: yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: yarn- - - name: Prepare license - run: | - mkdir -p ~/.dotcms/license/ - touch ~/.dotcms/license/license.dat - echo "${{ secrets.DOTCMS_LICENSE }}" > ~/.dotcms/license/license.dat - - id: run-postman-tests - name: Run Postman Tests - timeout-minutes: 90 - run: | - ./mvnw -Pcoverage $JVM_TEST_MAVEN_OPTS verify \ - -pl :dotcms-postman -Dpostman.test.skip=false \ - -Dpostman.collections=${{ matrix.collection_group }} \ - -Ddotcms.image.name=${DOCKER_IMAGE}:${DOCKER_TAG} - pec=$? - [[ pec -eq 0 ]] || exit pec - - name: Prepare reports archive (if maven failed) - if: failure() - shell: bash - run: | - find . -name '*-reports' -type d - tree ./dotcms-postman - find . -name '*-reports' -type d | tar -czf test-reports.tgz -T - - - name: Upload failure Archive (if maven failed) - uses: actions/upload-artifact@v4 - if: failure() - with: - name: test-reports-postman-${{ matrix.collection_group }} - path: 'test-reports.tgz' - - name: failsafe-postman-tests # Uploads will be merged with same name - uses: actions/upload-artifact@v4 - if: always() - with: - name: "build-reports-test-postman - ${{ matrix.collection_group }}" - path: | - dotcms-postman/target/failsafe-reports/*.xml - dotcms-postman/target/jacoco-report/*.exec - target/build-report.json - LICENSE - retention-days: 2 \ No newline at end of file + artifacts-from: ${{ env.ARTIFACT_RUN_ID }} \ No newline at end of file diff --git a/.github/workflows/reusable-sonarqube.yml b/.github/workflows/reusable-sonarqube.yml index 16a37eeafded..571767e3cdfa 100644 --- a/.github/workflows/reusable-sonarqube.yml +++ b/.github/workflows/reusable-sonarqube.yml @@ -22,58 +22,15 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Setup master branch locally without switching current branch - if: github.ref != 'refs/heads/master' - run: git fetch origin master:master - - name: Set up JDK 17 - uses: actions/setup-java@v4 + - name: Prepare Maven + uses: ./.github/actions/maven-job with: - java-version: 17 - distribution: 'temurin' - - name: Get Date - id: get-date - run: | - echo "date=$(/bin/date -u "+%Y-%m")" >> $GITHUB_OUTPUT - shell: bash - - name: Download Maven Repo - uses: actions/download-artifact@v4 - with: - run-id: ${{ inputs.artifact-run-id }} - github-token: ${{ secrets.GITHUB_TOKEN }} - name: maven-repo - path: ~/.m2/repository - continue-on-error: true - - name: Download Build Classes - uses: actions/download-artifact@v4 - with: - run-id: ${{ inputs.artifact-run-id }} - github-token: ${{ secrets.GITHUB_TOKEN }} - name: "build-classes-Initial Artifact Build" - continue-on-error: true - - name: Cache SonarQube packages - uses: actions/cache@v4 - with: - path: ~/.sonar/cache - key: ${{ runner.os }}-sonar - restore-keys: ${{ runner.os }}-sonar - # download the coverage execution files - - name: Download build reports - id: download-artifact - uses: dawidd6/action-download-artifact@v3.0.0 - with: - name: build-reports-test-.* - run_id: ${{ inputs.artifact-run-id }} - name_is_regexp: true - path: dotcms-core/target/build-reports - if_no_artifact_found: warn - - name: Maven Build No Test - env: - MAVEN_OPTS: "-Xmx2048m" - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} - shell: bash - run: | - ./mvnw $JVM_TEST_MAVEN_OPTS -Dsonar.ws.timeout=180 -Dsonar.log.level=DEBUG org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=dotCMS_core_AYSbIemxK43eThAXTlt- -Dsonar.host.url=${SONAR_HOST_URL} -Dsonar.token=$SONAR_TOKEN + stage-name: "SonarQube Scan" + restore-classes: true + require-master: true + cache-sonar: true + java-version: 21.0.3-ms # does not work with java 11, remove once we are on java 21 + maven-args: -Dsonar.ws.timeout=180 -Dsonar.log.level=DEBUG org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=dotCMS_core_AYSbIemxK43eThAXTlt- -Dsonar.host.url=${{ secrets.SONAR_HOST_URL }} -Dsonar.token=${{ secrets.SONAR_TOKEN }} - name: SonarQube Quality Gate check id: sonarqube-quality-gate-check uses: sonarsource/sonarqube-quality-gate-action@master diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 000000000000..a4b68d22dc65 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v18.20.3 \ No newline at end of file diff --git a/core-web/pom.xml b/core-web/pom.xml index 036b7342443c..30baad32f189 100644 --- a/core-web/pom.xml +++ b/core-web/pom.xml @@ -95,6 +95,33 @@ ${yarn.install.cmd} + + + lint-test + + yarn + + + generate-resources + + ${skip.validate} + nx affected -t lint --exclude='tag:skip:lint' + + + + + format-test + + yarn + + + generate-resources + + ${skip.validate} + nx format:check + + + build dotcms-ui @@ -257,32 +284,9 @@ validate - - generate-resources - - - com.github.eirslett - frontend-maven-plugin - - - ${skip.validate} - - - - lint-test - - yarn - - - generate-resources - - nx affected -t lint --exclude='tag:skip:lint' - - - - - - + + false + diff --git a/nodejs-parent/pom.xml b/nodejs-parent/pom.xml index 84b09339f14b..3ccc5684333d 100644 --- a/nodejs-parent/pom.xml +++ b/nodejs-parent/pom.xml @@ -56,6 +56,25 @@ + + + maven-antrun-plugin + + + create-root-npmrc + process-resources + + + echo "Using node.js ${node.js.version}" for project default + ${node.js.version} + + + + run + + + + diff --git a/parent/pom.xml b/parent/pom.xml index c77fe997261e..cf77b55ccc51 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -1163,6 +1163,15 @@ + + prod + + false + + + + + jprofiler diff --git a/tools/dotcms-cli/cli/pom.xml b/tools/dotcms-cli/cli/pom.xml index ffe83e542038..c134be9ce2a7 100644 --- a/tools/dotcms-cli/cli/pom.xml +++ b/tools/dotcms-cli/cli/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> dotcms-cli-parent com.dotcms @@ -146,6 +146,7 @@ ${testcontainers.docker.image} + true diff --git a/tools/dotcms-cli/jreleaser.yml b/tools/dotcms-cli/jreleaser.yml index 7cf1cb20d259..b85247a10bfe 100644 --- a/tools/dotcms-cli/jreleaser.yml +++ b/tools/dotcms-cli/jreleaser.yml @@ -47,7 +47,7 @@ distributions: active: ALWAYS stereotype: CLI artifacts: - - path: '{{artifactsDir}}/{{artifactsDir}}-linux-x86_64/dotcms-cli-{{projectVersion}}-runner.jar' + - path: '{{m2Dir}}/com/dotcms/dotcms-cli/{{projectVersion}}/dotcms-cli-{{projectVersion}}-runner.jar' platform: 'linux-x86_64' extraProperties: optional: 'true' @@ -55,15 +55,15 @@ distributions: dotcms-cli-native: type: BINARY artifacts: - - path: '{{artifactsDir}}/{{artifactsDir}}-osx-aarch_64/distributions/dotcms-cli-{{projectVersion}}-osx-aarch_64.zip' + - path: '{{artifactsDir}}/artifacts-osx-aarch_64/distributions/dotcms-cli-{{projectVersion}}-osx-aarch_64.zip' platform: 'osx-aarch_64' extraProperties: optional: 'true' - - path: '{{artifactsDir}}/{{artifactsDir}}-osx-x86_64/distributions/dotcms-cli-{{projectVersion}}-osx-x86_64.zip' + - path: '{{artifactsDir}}/artifacts-osx-x86_64/distributions/dotcms-cli-{{projectVersion}}-osx-x86_64.zip' platform: 'osx-x86_64' extraProperties: optional: 'true' - - path: '{{artifactsDir}}/{{artifactsDir}}-linux-x86_64/distributions/dotcms-cli-{{projectVersion}}-linux-x86_64.zip' + - path: '{{artifactsDir}}/artifacts-linux-x86_64/distributions/dotcms-cli-{{projectVersion}}-linux-x86_64.zip' platform: 'linux-x86_64' extraProperties: optional: 'true'