diff --git a/.github/workflows/ci-pipeline.yml b/.github/workflows/ci-pipeline.yml new file mode 100644 index 000000000..f0e19ee36 --- /dev/null +++ b/.github/workflows/ci-pipeline.yml @@ -0,0 +1,114 @@ +name: Build with JFrog CLI (Forcing New Extractor) + +on: + push: + branches: + - main + - develop + + pull_request: + branches: [ "main" ] # Trigger workflow on pull requests targeting main + +jobs: + build: + runs-on: ubuntu-latest # Use the latest Ubuntu runner for execution + + steps: + ################################################# + # 1) Checkout the repository to the runner + ################################################# + - name: Checkout + uses: actions/checkout@v4 # Pulls the latest code from the repository + + ################################################# + # 2) Set up Java environment + ################################################# + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + distribution: 'temurin' # Use Eclipse Temurin JDK (OpenJDK) + java-version: '17' # Ensure Java 17 is installed + + ################################################# + # 3) Install and Configure JFrog CLI + ################################################# + - name: Setup JFrog CLI + uses: jfrog/setup-jfrog-cli@v4 # Official JFrog CLI GitHub Action + id: setup-cli + env: + JF_URL: ${{secrets.JF_RT_URL}} # Artifactory base URL (stored as a GitHub secret) + JFROG_CLI_RELEASES_REPO: 'https://trialt0zppb.jfrog.io/artifactory/petclinic-maven-dev-virtual/' + JFROG_CLI_EXTRACTORS_REMOTE: 'https://trialt0zppb.jfrog.io/artifactory/petclinic-maven-dev-virtual/' + JF_GIT_TOKEN: ${{secrets.GH_TOKEN}} # GitHub token for authentication + JF_USER: ${{secrets.ARTIFACTORY_USERNAME}} # Artifactory username + JF_PASSWORD: ${{secrets.ARTIFACTORY_IDENTITY_TOKEN}} # Artifactory identity token + + ################################################# + # 4) Clean the local Maven cache (optional but recommended) + ################################################# + - name: Clear local Maven cache + run: rm -rf ~/.m2/repository # Ensures a clean build by removing old dependencies + + - name: Ensure mvnw is executable + run: chmod +x mvnw # Make the Maven wrapper script executable + + ################################################# + # 5) Verify JFrog connection + ################################################# + - name: ping jfrog + run: jf rt ping + + ################################################# + # 6) Configure Maven to use JFrog as a repository + ################################################# + - name: configure maven + run: jf mvnc --global --repo-resolve-releases petclinic-maven-dev-virtual/ --repo-resolve-snapshots petclinic-maven-dev-virtual/ + # This sets up JFrog CLI to resolve dependencies from Artifactory + + ################################################# + # 7) Build project using JFrog CLI with Maven + ################################################# + - name: Maven Build With JFrog CLI + run: | + jf mvn clean install \ + -DskipTests=true -Denforcer.skip=true \ + --build-name="spring-petclinic" \ + --build-number="${{ github.run_id }}" + + ################################################# + # 8) Scan with XRay + ################################################# + - name: Scan Artifact + run: | + latest_jar=$(find target -name "*.jar" | sort | tail -n 1) + echo "Scanning: $latest_jar" + jf scan "$latest_jar" + + ################################################# + # 9) Build Docker image with local Docker + ################################################# + - name: Build Docker Image + run: | + docker build -t trialt0zppb.jfrog.io/petclinic-docker-dev-local/spring-petclinic:${{ github.run_id }} . + + ################################################# + # 10) Push Docker image using JFrog CLI + ################################################# + - name: Push Docker Image to Artifactory + run: | + jfrog rt docker-push \ + trialt0zppb.jfrog.io/petclinic-docker-dev-local/spring-petclinic:${{ github.run_id }} \ + petclinic-docker-dev-local \ + --build-name="spring-petclinic" \ + --build-number="${{ github.run_id }}" + + ################################################# + # 9) Publish Build Information to JFrog + ################################################# + - name: Publish Build Info + run: | + jfrog rt build-collect-env # Collect environment variables + jfrog rt build-add-dependencies . # Add dependencies found in the current directory + jfrog rt build-add-git # Add Git commit information + jfrog rt build-publish "spring-petclinic" "${{ github.run_id }}" + # Publishes build metadata (dependencies, artifacts, environment) to JFrog diff --git a/.github/workflows/frogbot-scan-pull-request.yml b/.github/workflows/frogbot-scan-pull-request.yml new file mode 100644 index 000000000..d5063a0fc --- /dev/null +++ b/.github/workflows/frogbot-scan-pull-request.yml @@ -0,0 +1,42 @@ +name: "Frogbot Scan Pull Request" +on: + pull_request_target: + types: [opened, synchronize] +permissions: + pull-requests: write + contents: read + # [Mandatory If using OIDC authentication protocol instead of JF_ACCESS_TOKEN] + # id-token: write +jobs: + scan-pull-request: + runs-on: ubuntu-latest + # A pull request needs to be approved before Frogbot scans it. Any GitHub user who is associated with the + # "frogbot" GitHub environment can approve the pull request to be scanned. + environment: frogbot + steps: + - uses: jfrog/frogbot@v2 + env: + # [Mandatory] + # JFrog platform URL + JF_URL: ${{ secrets.JF_URL }} + + # [Mandatory if JF_USER and JF_PASSWORD are not provided] + # JFrog access token with 'read' permissions on Xray service + # JF_ACCESS_TOKEN: ${{ secrets.JF_ACCESS_TOKEN }} + + # [Mandatory if JF_ACCESS_TOKEN is not provided] + # JFrog username with 'read' permissions for Xray. Must be provided with JF_PASSWORD + JF_USER: ${{ secrets.JF_USER }} + + # [Mandatory if JF_ACCESS_TOKEN is not provided] + # JFrog password. Must be provided with JF_USER + JF_PASSWORD: ${{ secrets.JF_ACCESS_TOKEN }} + + # [Mandatory] + # The GitHub token is automatically generated for the job + JF_GIT_TOKEN: ${{ secrets.JF_GIT_TOKEN }} + + # [Mandatory if using OIDC authentication protocol instead of JF_ACCESS_TOKEN] + # Insert to oidc-provider-name the 'Provider Name' defined in the OIDC integration configured in the JPD + # with: + # oidc-provider-name: "" \ No newline at end of file diff --git a/.github/workflows/frogbot-scan-repository.yml b/.github/workflows/frogbot-scan-repository.yml new file mode 100644 index 000000000..198487578 --- /dev/null +++ b/.github/workflows/frogbot-scan-repository.yml @@ -0,0 +1,50 @@ +name: "Frogbot Scan Repository" +on: + workflow_dispatch: + schedule: + # The repository will be scanned once a day at 00:00 GMT. + - cron: "0 0 * * *" +permissions: + contents: write + pull-requests: write + security-events: write + # [Mandatory If using OIDC authentication protocol instead of JF_ACCESS_TOKEN] + # id-token: write +jobs: + scan-repository: + runs-on: ubuntu-latest + strategy: + matrix: + # The repository scanning will be triggered periodically on the following branches. + branch: ["dev"] + steps: + - uses: jfrog/frogbot@v2 + env: + # [Mandatory] + # JFrog platform URL + JF_URL: ${{ secrets.JF_URL }} + + # [Mandatory if JF_USER and JF_PASSWORD are not provided] + # JFrog access token with 'read' permissions on Xray service + JF_ACCESS_TOKEN: ${{ secrets.JF_ACCESS_TOKEN }} + + # [Mandatory if JF_ACCESS_TOKEN is not provided] + # JFrog username with 'read' permissions for Xray. Must be provided with JF_PASSWORD + JF_USER: ${{ secrets.JF_USER }} + + # [Mandatory if JF_ACCESS_TOKEN is not provided] + # JFrog password. Must be provided with JF_USER + JF_PASSWORD: ${{ secrets.JF_ACCESS_TOKEN }} + + # [Mandatory] + # The GitHub token is automatically generated for the job + JF_GIT_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # [Mandatory] + # The name of the branch on which Frogbot will perform the scan + JF_GIT_BASE_BRANCH: ${{ matrix.branch }} + + # [Mandatory if using OIDC authentication protocol instead of JF_ACCESS_TOKEN] + # Insert to oidc-provider-name the 'Provider Name' defined in the OIDC integration configured in the JPD + # with: + # oidc-provider-name: "" \ No newline at end of file diff --git a/.github/workflows/gradle-build.yml b/.github/workflows/gradle-build.yml deleted file mode 100644 index c24c121b1..000000000 --- a/.github/workflows/gradle-build.yml +++ /dev/null @@ -1,31 +0,0 @@ -# This workflow will build a Java project with Gradle, and cache/restore any dependencies to improve the workflow execution time -# For more information see: https://docs.github.com/en/actions/use-cases-and-examples/building-and-testing/building-and-testing-java-with-gradle - -name: Java CI with Gradle - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -jobs: - build: - - runs-on: ubuntu-latest - strategy: - matrix: - java: [ '17' ] - - steps: - - uses: actions/checkout@v4 - - name: Set up JDK ${{matrix.java}} - uses: actions/setup-java@v4 - with: - java-version: ${{matrix.java}} - distribution: 'adopt' - cache: maven - - name: Setup Gradle - uses: gradle/actions/setup-gradle@v4 - - name: Build with Gradle - run: ./gradlew build diff --git a/.github/workflows/maven-build.yml b/.github/workflows/maven-build.yml deleted file mode 100644 index a1ec4dab7..000000000 --- a/.github/workflows/maven-build.yml +++ /dev/null @@ -1,29 +0,0 @@ -# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time -# For more information see: https://docs.github.com/en/actions/use-cases-and-examples/building-and-testing/building-and-testing-java-with-maven - -name: Java CI with Maven - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -jobs: - build: - - runs-on: ubuntu-latest - strategy: - matrix: - java: [ '17' ] - - steps: - - uses: actions/checkout@v4 - - name: Set up JDK ${{matrix.java}} - uses: actions/setup-java@v4 - with: - java-version: ${{matrix.java}} - distribution: 'adopt' - cache: maven - - name: Build with Maven Wrapper - run: ./mvnw -B verify diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 654af46a7..38efa3057 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -15,5 +15,5 @@ # specific language governing permissions and limitations # under the License. wrapperVersion=3.3.2 -distributionType=only-script +#distributionType=only-script distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..e3c8936d9 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,15 @@ +# Use an official OpenJDK runtime as a parent image +FROM openjdk:17-jdk-slim + +# Set the working directory inside the container +WORKDIR /app + +# Copy the built JAR file from the target directory +COPY target/spring-petclinic-*.jar app.jar + +# Expose the application port +EXPOSE 8080 + +# Run the application +CMD ["java", "-jar", "app.jar"] + diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 000000000..0eb8314a8 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,80 @@ +pipeline { + agent any + tools { + maven 'maven-3' + } + environment { + JFROG_URL = "https://trialt0zppb.jfrog.io/" + JFROG_REPO_RELEASES = "petclinic-maven-dev-local" + JFROG_REPO_SNAPSHOTS = "petclinic-maven-dev-virtual" + JFROG_CREDENTIALS_ID = 'jfrog-saas' + JFROG_CLI_BUILD_NAME = "spring-petclinic" + JFROG_CLI_BUILD_NUMBER = "${BUILD_ID}" + JF = "${WORKSPACE}/jfrog" + } + stages { + stage('Download JFrog CLI') { + steps { + sh """ + curl -fL https://releases.jfrog.io/artifactory/jfrog-cli/v2-jf/2.74.1/jfrog-cli-linux-amd64/jf -o "${JF}" + chmod +x "${JF}" + """ + } + } + + stage('Configure JFrog CLI') { + steps { + withCredentials([usernamePassword(credentialsId: "${JFROG_CREDENTIALS_ID}", usernameVariable: 'JFROG_USER', passwordVariable: 'JFROG_API_KEY')]) { + sh """ + ${JF} config add jenkins-config \ + --url=${JFROG_URL} \ + --user=${JFROG_USER} \ + --password=${JFROG_API_KEY} \ + --interactive=false \ + --overwrite=true + """ + } + } + } + + stage('Build with Maven') { + steps { + sh """ + ${JF} mvnc --global \\ + --repo-resolve-releases=${JFROG_REPO_SNAPSHOTS} \\ + --repo-resolve-snapshots=${JFROG_REPO_SNAPSHOTS} \\ + --repo-deploy-releases=${JFROG_REPO_RELEASES} \\ + --repo-deploy-snapshots=${JFROG_REPO_RELEASES} + """ + sh """ + ${JF} mvn clean deploy -DskipTests -Dcheckstyle.skip=true \\ + --build-name=${JFROG_CLI_BUILD_NAME} \\ + --build-number=${JFROG_CLI_BUILD_NUMBER} + """ + } + } + + stage('Publish Build Info') { + steps { + sh """ + ${JF} rt build-collect-env + ${JF} rt build-add-git + ${JF} rt build-publish + """ + } + } + + stage('Xray Scan') { + steps { + // Use the new "jf build-scan" command + // "Fail Build" is decided by your Xray policy if severity >= High + sh "${JF} build-scan ${JFROG_CLI_BUILD_NAME} ${JFROG_CLI_BUILD_NUMBER} --fail=false" + } + } + } + post { + always { + echo "Build complete: ${env.JFROG_CLI_BUILD_NAME} #${env.BUILD_NUMBER}" + } + } +} diff --git a/README.md b/README.md index c865c3b51..a2e6ff1f2 100644 --- a/README.md +++ b/README.md @@ -163,3 +163,4 @@ For additional details, please refer to the blog post [Hello DCO, Goodbye CLA: S ## License The Spring PetClinic sample application is released under version 2.0 of the [Apache License](https://www.apache.org/licenses/LICENSE-2.0). +frogbot test 1 \ No newline at end of file diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 000000000..e8f3d6f54 --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,22 @@ +# Maven +# Build your Java project and run tests with Apache Maven. +# Add steps that analyze code, save build artifacts, deploy, and more: +# https://docs.microsoft.com/azure/devops/pipelines/languages/java + +trigger: +- main + +pool: + vmImage: ubuntu-latest + +steps: +- task: Maven@3 + inputs: + mavenPomFile: 'pom.xml' + mavenOptions: '-Xmx3072m' + javaHomeOption: 'JDKVersion' + jdkVersionOption: '1.11' + jdkArchitectureOption: 'x64' + publishJUnitResults: true + testResultsFiles: '**/surefire-reports/TEST-*.xml' + goals: 'package'