mirror of
https://github.com/spring-projects/spring-petclinic.git
synced 2025-12-27 19:07:28 +00:00
apptrust flow
This commit is contained in:
parent
8571ca5667
commit
e1cb38a3a4
6 changed files with 542 additions and 457 deletions
329
.github/workflows/jf-cli.yml
vendored
329
.github/workflows/jf-cli.yml
vendored
|
|
@ -18,6 +18,7 @@ env:
|
|||
RBv2_SPEC_JSON: "rbv2-spec-info.json"
|
||||
#RBV2_SIGNING_KEY: "${{secrets.RBV2_SIGNING_KEY}}" # ref https://jfrog.com/help/r/jfrog-artifactory-documentation/create-signing-keys-for-release-bundles-v2
|
||||
DEFAULT_WORKSPACE: "${{github.workspace}}" # /home/runner/work/spring-petclinic/spring-petclinic
|
||||
PROJECT_KEY_APP_TRUST: "krishna-apptrust"
|
||||
jobs:
|
||||
dockerPackage:
|
||||
name: "Docker"
|
||||
|
|
@ -28,7 +29,7 @@ jobs:
|
|||
RT_REPO_DOCKER_VIRTUAL: "springpetclinic-docker-virtual"
|
||||
RT_REPO_DOCKER_DEFAULT_LOCAL: "springpetclinic-docker-snapshot-local" # springpetclinic-docker-dev-local, springpetclinic-docker-qa-local, springpetclinic-docker-prod-local
|
||||
RT_REPO_DEV_LOCAL: "springpetclinic-docker-dev-local"
|
||||
RT_REPO_QA_LOCAL: s"pringpetclinic-docker-qa-local"
|
||||
RT_REPO_QA_LOCAL: "springpetclinic-docker-qa-local"
|
||||
RT_REPO_PROD_LOCAL: "springpetclinic-docker-prod-local"
|
||||
DOCKER_BUILDX_PLATFORMS: 'linux/amd64,linux/arm64'
|
||||
DOCKER_METADATA_JSON: 'build-metadata.json'
|
||||
|
|
@ -788,6 +789,7 @@ jobs:
|
|||
ARTIFACT_DIGEST=$(sha256sum target/spring-petclinic-*.jar | awk '{print "sha256:"$1}')
|
||||
echo "artifact_digest=$ARTIFACT_DIGEST" >> $GITHUB_OUTPUT
|
||||
|
||||
|
||||
- name: "Evidence: Build Info"
|
||||
# continue-on-error: true
|
||||
env:
|
||||
|
|
@ -804,18 +806,6 @@ jobs:
|
|||
cat ./${{env.EVD_JSON}}
|
||||
jf evd create --build-name ${{env.BUILD_NAME}} --build-number ${{env.BUILD_ID}} --predicate ./${{env.EVD_JSON}} --predicate-type https://cyclonedx.org/bom/v1.4 --key "${{secrets.KRISHNAM_JFROG_EVD_PRIVATEKEY}}" --key-alias ${{secrets.EVIDENCE_KEY_ALIAS}}
|
||||
|
||||
- name: "Evidence: Test Results"
|
||||
continue-on-error: true
|
||||
env:
|
||||
PY_SCRIPT: "jfrog/convert/convert_surefire_to_json.py"
|
||||
EVD_JSON: "target/surefire-reports/test-results.json" # https://jfrog.com/evidence/signature/v1
|
||||
run: |
|
||||
jf mvn test -Denforcer.skip=true
|
||||
|
||||
python3 ./${{env.PY_SCRIPT}} ./${{env.EVD_JSON}}
|
||||
|
||||
cat ./${{env.EVD_JSON}}
|
||||
jf evd create --build-name ${{env.BUILD_NAME}} --build-number ${{env.BUILD_ID}} --predicate ./${{env.EVD_JSON}} --predicate-type https://jfrog.com/evidence/test-results/v1 --key "${{secrets.KRISHNAM_JFROG_EVD_PRIVATEKEY}}" --key-alias ${{secrets.EVIDENCE_KEY_ALIAS}}
|
||||
|
||||
# - name: "Evidence: Build Publish"
|
||||
# # continue-on-error: true
|
||||
|
|
@ -1366,4 +1356,315 @@ jobs:
|
|||
run: |
|
||||
cat ./${{env.EVD_JSON}}
|
||||
jf evd create --build-name ${{env.BUILD_NAME}} --build-number ${{env.BUILD_ID}} --predicate ./${{env.EVD_JSON}} --predicate-type https://cyclonedx.org/bom/v1.4 --key "${{secrets.KRISHNAM_JFROG_EVD_PRIVATEKEY}}" --key-alias ${{secrets.EVIDENCE_KEY_ALIAS}}
|
||||
|
||||
|
||||
|
||||
appTrustdockerPackage:
|
||||
name: "AppTrustDocker"
|
||||
env:
|
||||
BUILD_ID: "psj-at-dkr-${{github.run_number}}"
|
||||
RT_REPO_MVN_VIRTUAL: "krishna-apptrust-java-virtual"
|
||||
# RT_REPO_MVN_DEFAULT_LOCAL: "springpetclinic-mvn-snapshot-local" # springpetclinic-mvn-dev-local, springpetclinic-mvn-qa-local, springpetclinic-mvn-prod-local
|
||||
RT_REPO_DOCKER_VIRTUAL: "krishna-apptrust-docker-virtual"
|
||||
RT_REPO_DOCKER_DEFAULT_LOCAL: "krishna-apptrust-docker-init-local" # krishna-apptrust-docker-dev-local, krishna-apptrust-docker-prod-local, krishna-apptrust-docker-qa-local
|
||||
RT_REPO_DEV_LOCAL: "krishna-apptrust-docker-dev-local"
|
||||
RT_REPO_QA_LOCAL: "krishna-apptrust-docker-qa-local"
|
||||
RT_REPO_PROD_LOCAL: "krishna-apptrust-docker-prod-local"
|
||||
DOCKER_BUILDX_PLATFORMS: 'linux/amd64,linux/arm64'
|
||||
DOCKER_METADATA_JSON: 'build-metadata.json'
|
||||
defaults:
|
||||
run:
|
||||
working-directory: "${{env.DEFAULT_WORKSPACE}}"
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30 # ref https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idtimeout-minutes
|
||||
steps:
|
||||
# Use the specific setup-cli branch. Ref https://github.com/marketplace/actions/setup-jfrog-cli
|
||||
- name: "Setup JFrog CLI"
|
||||
uses: jfrog/setup-jfrog-cli@v4
|
||||
id: setup-cli
|
||||
env:
|
||||
JF_URL: ${{env.JF_RT_URL}}
|
||||
JFROG_CLI_LOG_LEVEL: ${{env.JFROG_CLI_LOG_LEVEL}}
|
||||
JFROG_CLI_RELEASES_REPO: '${{env.JF_RT_URL}}/artifactory/${{env.RT_REPO_MVN_VIRTUAL}}'
|
||||
JFROG_CLI_EXTRACTORS_REMOTE: '${{env.JF_RT_URL}}/artifactory/${{env.RT_REPO_MVN_VIRTUAL}}'
|
||||
JF_GIT_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||
with:
|
||||
version: latest #2.71.0
|
||||
oidc-provider-name: ${{vars.JF_OIDC_PROVIDER_NAME}}
|
||||
disable-job-summary: ${{env.JOB_SUMMARY}}
|
||||
|
||||
- name: "Clone VCS"
|
||||
uses: actions/checkout@v4 # ref: https://github.com/actions/checkout
|
||||
|
||||
- name: "setUp JDK provider = ${{env.JAVA_DISTRIBUTION}} with ver = ${{env.JAVA_VERSION}}"
|
||||
uses: actions/setup-java@v4 # ref https://github.com/actions/setup-java
|
||||
with:
|
||||
distribution: ${{env.JAVA_DISTRIBUTION}} # temurin
|
||||
java-version: ${{env.JAVA_VERSION}} # 25
|
||||
cache: 'maven'
|
||||
cache-dependency-path: 'pom.xml'
|
||||
|
||||
- name: "Software version"
|
||||
run: |
|
||||
# JFrog CLI version
|
||||
jf --version
|
||||
# Ping the server
|
||||
jf rt ping
|
||||
# Java
|
||||
java -version
|
||||
# MVN
|
||||
mvn -version
|
||||
# Docker
|
||||
docker -v
|
||||
# Python
|
||||
python3 -V
|
||||
pip3 -V
|
||||
# jf config
|
||||
jf config show
|
||||
|
||||
- name: "Config jf with mvn repos"
|
||||
run: |
|
||||
jf mvnc --global --repo-resolve-releases ${{env.RT_REPO_MVN_VIRTUAL}} --repo-resolve-snapshots ${{env.RT_REPO_MVN_VIRTUAL}}
|
||||
|
||||
- name: "Create ENV variables"
|
||||
run: |
|
||||
echo "ARTIFACT_NAME=$(mvn help:evaluate -Dexpression=project.artifactId -q -DforceStdout)" >> $GITHUB_ENV
|
||||
echo "ARTIFACT_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)" >> $GITHUB_ENV
|
||||
echo "TODAYS_DATE=$(date +'%Y-%m-%d')" >> $GITHUB_ENV
|
||||
echo "RT_REPO_DOCKER_IMG=${{env.RT_REPO_DOCKER_VIRTUAL}}/${{env.BUILD_NAME}}" >> $GITHUB_ENV
|
||||
echo "JF_REGISTRY=${{env.JF_RT_URL}}/${{env.RT_REPO_DOCKER_VIRTUAL}}" >> $GITHUB_ENV
|
||||
echo "RT_REPO_DOCKER_URL=${{vars.JF_NAME}}.jfrog.io/${{env.RT_REPO_DOCKER_VIRTUAL}}/${{env.BUILD_NAME}}:${{env.BUILD_ID}}" >> $GITHUB_ENV
|
||||
|
||||
|
||||
- name: "Docker authentication" # ref https://github.com/marketplace/actions/docker-login
|
||||
id: config-docker
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{env.JF_REGISTRY}}
|
||||
username: ${{steps.setup-cli.outputs.oidc-user}}
|
||||
password: ${{steps.setup-cli.outputs.oidc-token}}
|
||||
|
||||
- name: "Docker buildx instance"
|
||||
uses: docker/setup-buildx-action@v3 # ref: https://github.com/marketplace/actions/docker-setup-buildx h
|
||||
with:
|
||||
use: true
|
||||
platforms: ${{env.DOCKER_BUILDX_PLATFORMS}} # linux/amd64,linux/arm64 # ref: https://docs.docker.com/reference/cli/docker/buildx/create/#platform
|
||||
install: true
|
||||
|
||||
- name: "list folder"
|
||||
run: |
|
||||
pwd
|
||||
tree .
|
||||
|
||||
- name: "Docker: Summary "
|
||||
run: |
|
||||
echo "# :frog: :ship: Docker: Summary :pushpin:" >> $GITHUB_STEP_SUMMARY
|
||||
echo " " >> $GITHUB_STEP_SUMMARY
|
||||
echo " " >> $GITHUB_STEP_SUMMARY
|
||||
echo " - Installed JFrog CLI [$(jf --version)](https://jfrog.com/getcli/) and Java [${{env.JAVA_DISTRIBUTION}}](https://github.com/actions/setup-java) v${{env.JAVA_VERSION}} " >> $GITHUB_STEP_SUMMARY
|
||||
echo " - $(jf --version) " >> $GITHUB_STEP_SUMMARY
|
||||
echo " - $(mvn -v) " >> $GITHUB_STEP_SUMMARY
|
||||
echo " - $(docker -v) " >> $GITHUB_STEP_SUMMARY
|
||||
echo " - Docker buildx configured with platforms: [${{env.DOCKER_BUILDX_PLATFORMS}}](https://docs.docker.com/reference/cli/docker/buildx/create/#platform) " >> $GITHUB_STEP_SUMMARY
|
||||
echo " - Configured the JFrog Cli and Docker login with SaaS Artifactory OIDC integration " >> $GITHUB_STEP_SUMMARY
|
||||
echo " " >> $GITHUB_STEP_SUMMARY
|
||||
echo " - Variables info" >> $GITHUB_STEP_SUMMARY
|
||||
echo " - App Trust project key: ${{env.PROJECT_KEY_APP_TRUST}} " >> $GITHUB_STEP_SUMMARY
|
||||
echo " - ID: ${{env.BUILD_ID}} " >> $GITHUB_STEP_SUMMARY
|
||||
echo " - Build Name: ${{env.BUILD_NAME}} " >> $GITHUB_STEP_SUMMARY
|
||||
echo " - Maven Repo URL: ${{env.RT_REPO_MVN_VIRTUAL}}" >> $GITHUB_STEP_SUMMARY
|
||||
echo " - Docker Repo URL: ${{env.RT_REPO_DOCKER_VIRTUAL}}" >> $GITHUB_STEP_SUMMARY
|
||||
echo " - Docker Image: ${{env.RT_REPO_DOCKER_IMG}}" >> $GITHUB_STEP_SUMMARY
|
||||
echo " - Docker URL: ${{env.RT_REPO_DOCKER_URL}}" >> $GITHUB_STEP_SUMMARY
|
||||
echo " " >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
# Package
|
||||
- name: "Curation: audit" # https://docs.jfrog-applications.jfrog.io/jfrog-applications/jfrog-cli/cli-for-jfrog-security/cli-for-jfrog-curation
|
||||
timeout-minutes: 15 # ref https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idstepstimeout-minutes
|
||||
continue-on-error: true # ref: https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idstepscontinue-on-error
|
||||
run: |
|
||||
rm -rf build.gradle
|
||||
jf ca --format=table --threads=100
|
||||
|
||||
- name: "Xray & JAS: Audit" # https://docs.jfrog-applications.jfrog.io/jfrog-applications/jfrog-cli/cli-for-jfrog-security
|
||||
# scan for Xray: Source code dependencies and JAS: Secrets Detection, IaC, Vulnerabilities Contextual Analysis 'SAST'
|
||||
timeout-minutes: 15 # ref: https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idstepstimeout-minutes
|
||||
# continue-on-error: true # ref: https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idstepscontinue-on-error
|
||||
run: |
|
||||
jf audit --mvn --sast=true --sca=true --secrets=true --licenses=true --validate-secrets=true --vuln=true --format=table --extended-table=true --threads=100 --fail=false --project=${{env.PROJECT_KEY_APP_TRUST}}
|
||||
|
||||
- name: "Package: Create MVN Build"
|
||||
# jf mvn clean install -DskipTests=true -Denforcer.skip=true --build-name=${{env.BUILD_NAME}} --build-number=${{env.BUILD_ID}}
|
||||
run: | # -Djar.finalName=${{env.JAR_FINAL_NAME}}
|
||||
mvn clean install -DskipTests=true -Denforcer.skip=true
|
||||
|
||||
- name: "Package: Xray - mvn Artifact scan"
|
||||
timeout-minutes: 15 # ref: https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idstepstimeout-minutes
|
||||
continue-on-error: true # ref: https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idstepscontinue-on-error
|
||||
run: |
|
||||
jf scan . --format=table --extended-table=true --threads=100 --fail=false --project=${{env.PROJECT_KEY_APP_TRUST}}
|
||||
|
||||
- name: "Package: Docker build and push"
|
||||
env:
|
||||
JAR_FILE: "./target/${{env.ARTIFACT_NAME}}-${{env.ARTIFACT_VERSION}}.jar"
|
||||
TAG10: "${{vars.JF_NAME}}.jfrog.io/${{env.RT_REPO_DOCKER_VIRTUAL}}/${{env.ARTIFACT_NAME}}:${{env.ARTIFACT_VERSION}}"
|
||||
TAG11: "${{vars.JF_NAME}}.jfrog.io/${{env.RT_REPO_DOCKER_VIRTUAL}}/${{env.ARTIFACT_NAME}}:${{env.TODAYS_DATE}}"
|
||||
TAG12: "${{vars.JF_NAME}}.jfrog.io/${{env.RT_REPO_DOCKER_VIRTUAL}}/${{env.ARTIFACT_NAME}}:${{env.BUILD_ID}}"
|
||||
TAG13: "${{vars.JF_NAME}}.jfrog.io/${{env.RT_REPO_DOCKER_VIRTUAL}}/${{env.ARTIFACT_NAME}}:latest"
|
||||
run: |
|
||||
docker image build -f ./jfrog/AppTrustDockerfile --build-arg JAR_FILE=${{env.JAR_FILE}} --platform "${{env.DOCKER_BUILDX_PLATFORMS}}" --metadata-file "${{env.DOCKER_METADATA_JSON}}" --push . -t ${{env.TAG10}} -t ${{env.TAG11}} -t ${{env.TAG12}} -t ${{env.TAG13}}
|
||||
|
||||
- name: "Optional: Docker pull image"
|
||||
run: |
|
||||
docker pull ${{env.RT_REPO_DOCKER_URL}}
|
||||
|
||||
- name: "Package: Docker image list"
|
||||
run: |
|
||||
docker image ls
|
||||
|
||||
# Evidence - Package references
|
||||
# Docs# https://jfrog.com/help/r/jfrog-artifactory-documentation/evidence-management
|
||||
# CLI# https://docs.jfrog-applications.jfrog.io/jfrog-applications/jfrog-cli/binaries-management-with-jfrog-artifactory/evidence-service
|
||||
- name: "Evidence: Package"
|
||||
# continue-on-error: true
|
||||
run: |
|
||||
echo '{ "actor": "${{github.actor}}", "pipeline": "github actions","build_name": "${{env.BUILD_NAME}}", "build_id": "${{env.BUILD_ID}}", "evd":"Evidence-Package", "package":"${{env.RT_REPO_DOCKER_URL}}" }' > ./${{env.EVIDENCE_SPEC_JSON}}
|
||||
cat ./${{env.EVIDENCE_SPEC_JSON}}
|
||||
jf evd create --package-name ${{env.BUILD_NAME}} --package-version ${{env.BUILD_ID}} --package-repo-name ${{env.RT_REPO_DOCKER_VIRTUAL}} --key "${{secrets.KRISHNAM_JFROG_EVD_PRIVATEKEY}}" --key-alias ${{secrets.EVIDENCE_KEY_ALIAS}} --predicate ./${{env.EVIDENCE_SPEC_JSON}} --predicate-type https://jfrog.com/evidence/signature/v1
|
||||
#echo " - Evidence for PACKAGE attached. Info available SaaS >> tab: Application >> left menu: Artifactory >> Packages >> ${{env.BUILD_NAME}} " >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: "Package: Xray - docker Artifact scan"
|
||||
timeout-minutes: 15 # ref https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idstepstimeout-minutes
|
||||
continue-on-error: true # ref: https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idstepscontinue-on-error
|
||||
run: |
|
||||
jf docker scan ${{env.RT_REPO_DOCKER_URL}} --build-name ${{env.BUILD_NAME}} --build-number ${{env.BUILD_ID}} --format=table --extended-table=true --detailed-summary=true --vuln=true --licenses=true --threads=100 --fail=false
|
||||
|
||||
- name: "Optional: Set env vars for BuildInfo" # These properties were captured in Builds >> spring-petclinic >> version >> Environment tab
|
||||
run: |
|
||||
export job="github-action" org="ps" team="architecture" product="jfrog-saas"
|
||||
|
||||
# Build Info
|
||||
# US
|
||||
# Executive Order:
|
||||
# https://www.whitehouse.gov/briefing-room/presidential-actions/2021/05/12/executive-order-on-improving-the-nations-cybersecurity/
|
||||
# https://www.nist.gov/itl/executive-order-14028-improving-nations-cybersecurity
|
||||
# US Dept of Commerce: https://www.ntia.gov/page/software-bill-materials
|
||||
# US Cyber Defence Agency: https://www.cisa.gov/sbom
|
||||
# NIST: https://www.nist.gov/itl/executive-order-14028-improving-nations-cybersecurity/software-security-supply-chains-software-1
|
||||
# NITA: https://www.ntia.gov/page/software-bill-materials
|
||||
# Centers for Medicare & Medicaid Services: https://security.cms.gov/learn/software-bill-materials-sbom
|
||||
# India
|
||||
# CERT-IN: https://www.cert-in.org.in/sbom/
|
||||
- name: "BuildInfo: Collect env"
|
||||
run: jf rt bce ${{env.BUILD_NAME}} ${{env.BUILD_ID}} --project=${{env.PROJECT_KEY_APP_TRUST}}
|
||||
|
||||
- name: "BuildInfo: Adds dependencies"
|
||||
continue-on-error: true
|
||||
run: jf rt bad ${{env.BUILD_NAME}} ${{env.BUILD_ID}} --project=${{env.PROJECT_KEY_APP_TRUST}}
|
||||
|
||||
- name: "BuildInfo: Add VCS info"
|
||||
run: jf rt bag ${{env.BUILD_NAME}} ${{env.BUILD_ID}} --project=${{env.PROJECT_KEY_APP_TRUST}}
|
||||
|
||||
- name: "BuildInfo: Docker build create"
|
||||
run: |
|
||||
imageDigest=$(cat "${{env.DOCKER_METADATA_JSON}}" | jq '.["containerimage.digest"]')
|
||||
echo "DOCKER_IMAGE_DIGEST: ${imageDigest}"
|
||||
|
||||
echo "DOCKER_IMAGE_DIGEST=${imageDigest}" >> $GITHUB_ENV. # set env var for next steps
|
||||
|
||||
echo "${{env.RT_REPO_DOCKER_URL}}@${imageDigest}" > ${{env.DOCKER_METADATA_JSON}}
|
||||
|
||||
jf rt bdc ${{env.RT_REPO_DOCKER_VIRTUAL}} --image-file ${{env.DOCKER_METADATA_JSON}} --build-name=${{env.BUILD_NAME}} --build-number=${{env.BUILD_ID}} --project=${{env.PROJECT_KEY_APP_TRUST}} --project=${{env.PROJECT_KEY_APP_TRUST}}
|
||||
|
||||
- name: "BuildInfo: Build Publish"
|
||||
run: jf rt bp ${{env.BUILD_NAME}} ${{env.BUILD_ID}} --detailed-summary=true --project=${{env.PROJECT_KEY_APP_TRUST}}
|
||||
|
||||
# Evidence - Build references
|
||||
# Docs# https://jfrog.com/help/r/jfrog-artifactory-documentation/evidence-management
|
||||
# CLI# https://docs.jfrog-applications.jfrog.io/jfrog-applications/jfrog-cli/binaries-management-with-jfrog-artifactory/evidence-service
|
||||
- name: "Evidence: Build Publish"
|
||||
# continue-on-error: true
|
||||
run: |
|
||||
echo '{ "actor": "${{github.actor}}", "pipeline": "github actions","build_name": "${{env.BUILD_NAME}}", "build_id": "${{env.BUILD_ID}}", "evd": "Evidence-BuildPublish"}' > ./${{env.EVIDENCE_SPEC_JSON}}
|
||||
cat ./${{env.EVIDENCE_SPEC_JSON}}
|
||||
jf evd create --build-name ${{env.BUILD_NAME}} --build-number ${{env.BUILD_ID}} --predicate ./${{env.EVIDENCE_SPEC_JSON}} --predicate-type https://jfrog.com/evidence/signature/v1 --key "${{secrets.KRISHNAM_JFROG_EVD_PRIVATEKEY}}" --key-alias ${{secrets.EVIDENCE_KEY_ALIAS}}
|
||||
#echo " - Evidence for BUILD Publish attached. " >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
# curl -L 'https://psazuse.jfrog.io/xray/api/v1/binMgr/builds' -H 'Content-Type: application/json' -H 'Authorization: ••••••' -d '{ "names": ["spring-petclinic"] }'
|
||||
- name: "Optional: Add Builds to Indexing Configuration"
|
||||
run: |
|
||||
jf xr curl "/api/v1/binMgr/builds" -H 'Content-Type: application/json' -d '{"names": ["${{env.BUILD_NAME}}"] }'
|
||||
# Set properties
|
||||
- name: "Optional: Set prop for Artifact" # These properties were captured Artifacts >> repo path 'spring-petclinic.---.jar' >> Properties
|
||||
run: |
|
||||
ts="cmd.$(date '+%Y-%m-%d-%H-%M')"
|
||||
jf rt sp "job=github-action;env=demo;org=ps;team=arch;pack_cat=webapp;build=maven;product=artifactory;features=package,buildinfo;ts=ts-${BUILD_ID}" --build="${{env.BUILD_NAME}}/${{env.BUILD_ID}}"
|
||||
|
||||
- name: "Optional: Query build info"
|
||||
env:
|
||||
BUILD_INFO_JSON: "BuildInfo-${{env.BUILD_ID}}.json"
|
||||
run: |
|
||||
jf rt curl "/api/build/${{env.BUILD_NAME}}/${{env.BUILD_ID}}" -o $BUILD_INFO_JSON
|
||||
cat $BUILD_INFO_JSON
|
||||
|
||||
- name: "Sleep for few seconds"
|
||||
env:
|
||||
SLEEP_TIME: 30
|
||||
run: |
|
||||
echo "Sleeping for ${{env.SLEEP_TIME}} seconds..."
|
||||
sleep ${{env.SLEEP_TIME}} # Sleeping for 20 seconds before executing the build publish seems to have resolved the build-scan issue. This delay might be helping with synchronization or resource availability, ensuring a smooth build process.
|
||||
echo "Awake now!"
|
||||
|
||||
- name: "Optional: Query - Build Scan status"
|
||||
run: |
|
||||
jf xr curl "/api/v1/build/status" -H 'Content-Type: application/json' -d '{"name": "${{env.BUILD_NAME}}", "number": "${{env.BUILD_ID}}" }'
|
||||
|
||||
# ref https://docs.jfrog-applications.jfrog.io/jfrog-applications/jfrog-cli/cli-for-jfrog-security/enrich-your-sbom
|
||||
# MVN plugin '<artifactId>cyclonedx-maven-plugin</artifactId>' is used to generate SBOM information in the CycloneDX format# target/classes/META-INF/sbom/application.cdx.json
|
||||
# ref https://spring.io/blog/2024/05/24/sbom-support-in-spring-boot-3-3
|
||||
- name: "Optional: Xray sbom-enrich"
|
||||
run: |
|
||||
jf se "target/classes/META-INF/sbom/application.cdx.json" --threads=100
|
||||
|
||||
- name: "BuildInfo: Xray - Build scan"
|
||||
timeout-minutes: 15 # ref https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idstepstimeout-minutes
|
||||
continue-on-error: true # ref: https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idstepscontinue-on-error
|
||||
run: |
|
||||
jf bs ${{env.BUILD_NAME}} ${{env.BUILD_ID}} --fail=false --format=table --extended-table=true --rescan=false --vuln=true --project=${{env.PROJECT_KEY_APP_TRUST}}
|
||||
|
||||
- name: "Optional: Build Scan V2" # https://jfrog.com/help/r/xray-rest-apis/scan-build-v2
|
||||
# jf xr curl /api/v2/ci/build -H 'Content-Type: application/json' -d '{"build_name": "spring-petclinic", "build_number": "ga-gdl-xray-50","rescan":true }'
|
||||
run: |
|
||||
jf xr curl /api/v2/ci/build -H 'Content-Type: application/json' -d '{"build_name": "${{env.BUILD_NAME}}", "build_number": "${{env.BUILD_ID}}","rescan":false }'
|
||||
|
||||
# Release Bundle v2
|
||||
- name: "RLM: RBv2 spec - create"
|
||||
run: |
|
||||
echo "{ \"files\": [ {\"build\": \"${{env.BUILD_NAME}}/${{env.BUILD_ID}}\", \"includeDeps\":\"true\"} ] }" > ${{env.RBv2_SPEC_JSON}}
|
||||
|
||||
- name: "RLM: RBv2 Create NEW"
|
||||
run: |
|
||||
cat ${{env.RBv2_SPEC_JSON}}
|
||||
jf rbc ${{env.BUILD_NAME}} ${{env.BUILD_ID}} --sync=true --signing-key=${{secrets.RBV2_SIGNING_KEY}} --spec=${{env.RBv2_SPEC_JSON}} --project=${{env.PROJECT_KEY_APP_TRUST}}
|
||||
|
||||
- name: "RLM: Xray Indexing"
|
||||
run: |
|
||||
jf xr curl "/api/v1/binMgr/release_bundle_v2" -H 'Content-Type: application/json' -d "{\"names\": [\"${{env.BUILD_NAME}}\"] }"
|
||||
|
||||
# Evidence - RBv2 new references
|
||||
# Docs# https://jfrog.com/help/r/jfrog-artifactory-documentation/evidence-management
|
||||
# CLI# https://docs.jfrog-applications.jfrog.io/jfrog-applications/jfrog-cli/binaries-management-with-jfrog-artifactory/evidence-service
|
||||
- name: "Evidence: RBv2 state NEW"
|
||||
# continue-on-error: true
|
||||
env:
|
||||
# https://psazuse.jfrog.io/ui/artifactory/lifecycle/?bundleName=spring-petclinic&bundleToFlash=spring-petclinic&repositoryKey=release-bundles-v2&activeKanbanTab=promotion
|
||||
NAME_LINK: "${{env.JF_RT_URL}}/ui/artifactory/lifecycle/?bundleName=${{env.BUILD_NAME}}&bundleToFlash=${{env.BUILD_NAME}}&repositoryKey=release-bundles-v2&activeKanbanTab=promotion"
|
||||
VER_LINK: "${{env.JF_RT_URL}}/ui/artifactory/lifecycle/?bundleName='${{env.BUILD_NAME}}'&bundleToFlash='${{env.BUILD_NAME}}'&releaseBundleVersion='${{env.BUILD_ID}}'&repositoryKey=release-bundles-v2&activeVersionTab=Version%20Timeline&activeKanbanTab=promotion"
|
||||
run: |
|
||||
echo '{ "actor": "${{github.actor}}", "pipeline": "github actions", "build_name": "${{env.BUILD_NAME}}", "build_id": "${{env.BUILD_ID}}", "evd": "Evidence-RBv2", "rbv2_stage": "NEW" }' > ./${{env.EVIDENCE_SPEC_JSON}}
|
||||
cat ./${{env.EVIDENCE_SPEC_JSON}}
|
||||
jf evd create --release-bundle ${{env.BUILD_NAME}} --release-bundle-version ${{env.BUILD_ID}} --predicate ./${{env.EVIDENCE_SPEC_JSON}} --predicate-type https://jfrog.com/evidence/promotion/v1 --key "${{secrets.KRISHNAM_JFROG_EVD_PRIVATEKEY}}" --key-alias ${{secrets.EVIDENCE_KEY_ALIAS}} --project=${{env.PROJECT_KEY_APP_TRUST}}
|
||||
|
||||
|
||||
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -11,6 +11,7 @@ build/
|
|||
!**/src/test/**/build/
|
||||
|
||||
### STS ###
|
||||
test-results.json
|
||||
.attach_pid*
|
||||
.apt_generated
|
||||
.classpath
|
||||
|
|
|
|||
17
jfrog/AppTrustDockerfile
Executable file
17
jfrog/AppTrustDockerfile
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
# base image https://hub.docker.com/layers/library/openjdk/17-jdk-alpine/
|
||||
# FROM openjdk:17-jdk-alpine
|
||||
# https://hub.docker.com/_/amazoncorretto/
|
||||
FROM psazuse.jfrog.io/krishna-apptrust-docker-virtual/amazoncorretto:25-alpine-jdk
|
||||
|
||||
# Set environment variables ref: https://docs.docker.com/build/building/variables/#env-usage-example
|
||||
ARG JAR_FILE
|
||||
# ENV JAR_FILE=spring-petclinic-3.4.0-SNAPSHOT.jar
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY ${JAR_FILE} /app/spring-petclinic.jar
|
||||
|
||||
# Set the command to run the Spring Boot application
|
||||
# java -jar target/spring-petclinic-3.2.0-SNAPSHOT.jar --server.port=7080
|
||||
# CMD java -jar ${JAR_FILE}
|
||||
CMD ["java", "-jar", "spring-petclinic.jar"]
|
||||
202
jfrog/convertXml2Json.sh
Executable file
202
jfrog/convertXml2Json.sh
Executable file
|
|
@ -0,0 +1,202 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Converts Maven Surefire XML test reports to a single JSON file.
|
||||
# Reads all *.xml files from target/surefire-reports/ and converts them to JSON.
|
||||
# Usage: ./jfrog/convertXml2Json.sh test-results.json
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Find project root directory
|
||||
# SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(pwd)"
|
||||
REPORTS_DIR="$PROJECT_ROOT/target/surefire-reports"
|
||||
OUTPUT_FILE="${1:-$PROJECT_ROOT/test-results.json}"
|
||||
|
||||
# Check if reports directory exists
|
||||
if [ ! -d "$REPORTS_DIR" ]; then
|
||||
echo "Error: Reports directory does not exist: $REPORTS_DIR" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if xq is available (XML to JSON converter, part of yq package)
|
||||
if ! command -v xq &> /dev/null; then
|
||||
echo "Error: xq command not found. Please install yq (which includes xq)." >&2
|
||||
echo " macOS: brew install yq" >&2
|
||||
echo " Linux: apt-get install yq or yum install yq" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if jq is available (for JSON manipulation)
|
||||
if ! command -v jq &> /dev/null; then
|
||||
echo "Error: jq command not found. Please install jq." >&2
|
||||
echo " macOS: brew install jq" >&2
|
||||
echo " Linux: apt-get install jq or yum install jq" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Find all XML files in the reports directory
|
||||
XML_FILES=("$REPORTS_DIR"/*.xml)
|
||||
|
||||
if [ ! -e "${XML_FILES[0]}" ]; then
|
||||
echo "Error: No XML files found in $REPORTS_DIR" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Found ${#XML_FILES[@]} XML test report file(s)..."
|
||||
|
||||
# Initialize arrays and counters
|
||||
SUITES_JSON="[]"
|
||||
TOTAL_TESTS=0
|
||||
TOTAL_FAILURES=0
|
||||
TOTAL_ERRORS=0
|
||||
TOTAL_SKIPPED=0
|
||||
TOTAL_TIME=0
|
||||
|
||||
# Process each XML file
|
||||
echo "Deleting existing output file: $OUTPUT_FILE"
|
||||
rm -rf "$OUTPUT_FILE"
|
||||
echo "Output file deleted: $OUTPUT_FILE"
|
||||
|
||||
echo "Processing XML files..."
|
||||
for xml_file in "${XML_FILES[@]}"; do
|
||||
if [ ! -f "$xml_file" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "Processing: $(basename "$xml_file")"
|
||||
|
||||
# Convert XML to JSON using xq
|
||||
# xq converts XML to JSON, and we use jq to extract and format the data
|
||||
suite_json=$(xq -c '.' "$xml_file" 2>/dev/null)
|
||||
|
||||
# Validate that we got valid JSON
|
||||
if [ -z "$suite_json" ] || ! echo "$suite_json" | jq empty 2>/dev/null; then
|
||||
echo "Warning: Failed to parse $xml_file or invalid JSON output, skipping..." >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
# Extract suite information and test cases using a single jq call to get all values
|
||||
suite_data=$(echo "$suite_json" | jq -c '{
|
||||
name: (.testsuite."@name" // .testsuite.name // "Unknown"),
|
||||
tests: ((.testsuite."@tests" // .testsuite.tests // 0) | if type == "string" and . == "" then 0 else (tonumber // 0) end),
|
||||
failures: ((.testsuite."@failures" // .testsuite.failures // 0) | if type == "string" and . == "" then 0 else (tonumber // 0) end),
|
||||
errors: ((.testsuite."@errors" // .testsuite.errors // 0) | if type == "string" and . == "" then 0 else (tonumber // 0) end),
|
||||
skipped: ((.testsuite."@skipped" // .testsuite.skipped // 0) | if type == "string" and . == "" then 0 else (tonumber // 0) end),
|
||||
time: ((.testsuite."@time" // .testsuite.time // 0) | if type == "string" and . == "" then 0 else (tonumber // 0) end),
|
||||
testCases: (
|
||||
.testsuite.testcase as $testcases |
|
||||
if $testcases == null then []
|
||||
elif $testcases | type == "array" then
|
||||
$testcases | map({
|
||||
name: (."@name" // .name // ""),
|
||||
classname: (."@classname" // .classname // ""),
|
||||
time: ((."@time" // .time // 0) | tonumber),
|
||||
failure: (if .failure then {
|
||||
message: (.failure."@message" // .failure.message // ""),
|
||||
type: (.failure."@type" // .failure.type // ""),
|
||||
content: (.failure."#text" // .failure.content // .failure // "")
|
||||
} else null end),
|
||||
error: (if .error then {
|
||||
message: (.error."@message" // .error.message // ""),
|
||||
type: (.error."@type" // .error.type // ""),
|
||||
content: (.error."#text" // .error.content // .error // "")
|
||||
} else null end),
|
||||
skipped: (if .skipped then (."@message" // .skipped."@message" // .skipped."#text" // .skipped // "") else null end)
|
||||
})
|
||||
else
|
||||
[{
|
||||
name: ($testcases."@name" // $testcases.name // ""),
|
||||
classname: ($testcases."@classname" // $testcases.classname // ""),
|
||||
time: (($testcases."@time" // $testcases.time // 0) | tonumber),
|
||||
failure: (if $testcases.failure then {
|
||||
message: ($testcases.failure."@message" // $testcases.failure.message // ""),
|
||||
type: ($testcases.failure."@type" // $testcases.failure.type // ""),
|
||||
content: ($testcases.failure."#text" // $testcases.failure.content // $testcases.failure // "")
|
||||
} else null end),
|
||||
error: (if $testcases.error then {
|
||||
message: ($testcases.error."@message" // $testcases.error.message // ""),
|
||||
type: ($testcases.error."@type" // $testcases.error.type // ""),
|
||||
content: ($testcases.error."#text" // $testcases.error.content // $testcases.error // "")
|
||||
} else null end),
|
||||
skipped: (if $testcases.skipped then ($testcases."@message" // $testcases.skipped."@message" // $testcases.skipped."#text" // $testcases.skipped // "") else null end)
|
||||
}]
|
||||
end
|
||||
)
|
||||
}')
|
||||
|
||||
# Extract individual values from suite_data
|
||||
suite_name=$(echo "$suite_data" | jq -r '.name')
|
||||
tests=$(echo "$suite_data" | jq -r '.tests')
|
||||
failures=$(echo "$suite_data" | jq -r '.failures')
|
||||
errors=$(echo "$suite_data" | jq -r '.errors')
|
||||
skipped=$(echo "$suite_data" | jq -r '.skipped')
|
||||
time=$(echo "$suite_data" | jq -r '.time')
|
||||
test_cases=$(echo "$suite_data" | jq -c '.testCases')
|
||||
|
||||
# Create suite object using the extracted values
|
||||
suite_object=$(jq -n \
|
||||
--arg name "$suite_name" \
|
||||
--argjson tests "$tests" \
|
||||
--argjson failures "$failures" \
|
||||
--argjson errors "$errors" \
|
||||
--argjson skipped "$skipped" \
|
||||
--argjson time "$time" \
|
||||
--argjson testCases "$test_cases" \
|
||||
'{
|
||||
name: $name,
|
||||
tests: $tests,
|
||||
failures: $failures,
|
||||
errors: $errors,
|
||||
skipped: $skipped,
|
||||
time: $time,
|
||||
testCases: $testCases
|
||||
}')
|
||||
|
||||
# Add suite to suites array
|
||||
SUITES_JSON=$(echo "$SUITES_JSON" | jq --argjson suite "$suite_object" '. + [$suite]')
|
||||
|
||||
# Update totals (extract integer values for arithmetic)
|
||||
tests_int=$(echo "$tests" | awk '{print int($1)}')
|
||||
failures_int=$(echo "$failures" | awk '{print int($1)}')
|
||||
errors_int=$(echo "$errors" | awk '{print int($1)}')
|
||||
skipped_int=$(echo "$skipped" | awk '{print int($1)}')
|
||||
|
||||
TOTAL_TESTS=$((TOTAL_TESTS + tests_int))
|
||||
TOTAL_FAILURES=$((TOTAL_FAILURES + failures_int))
|
||||
TOTAL_ERRORS=$((TOTAL_ERRORS + errors_int))
|
||||
TOTAL_SKIPPED=$((TOTAL_SKIPPED + skipped_int))
|
||||
# Use awk for floating point arithmetic (more portable than bc)
|
||||
TOTAL_TIME=$(awk "BEGIN {printf \"%.3f\", $TOTAL_TIME + $time}")
|
||||
done
|
||||
|
||||
# Create final JSON output
|
||||
FINAL_JSON=$(jq -n \
|
||||
--argjson totalTests "$TOTAL_TESTS" \
|
||||
--argjson totalFailures "$TOTAL_FAILURES" \
|
||||
--argjson totalErrors "$TOTAL_ERRORS" \
|
||||
--argjson totalSkipped "$TOTAL_SKIPPED" \
|
||||
--arg totalTime "$TOTAL_TIME" \
|
||||
--argjson suites "$SUITES_JSON" \
|
||||
'{
|
||||
summary: {
|
||||
totalTests: $totalTests,
|
||||
totalFailures: $totalFailures,
|
||||
totalErrors: $totalErrors,
|
||||
totalSkipped: $totalSkipped,
|
||||
totalTime: ($totalTime | tonumber)
|
||||
},
|
||||
suites: $suites
|
||||
}')
|
||||
|
||||
# Ensure output directory exists
|
||||
mkdir -p "$(dirname "$OUTPUT_FILE")"
|
||||
|
||||
# Write JSON file
|
||||
echo "$FINAL_JSON" | jq '.' > "$OUTPUT_FILE"
|
||||
|
||||
echo ""
|
||||
echo "Test results converted to JSON: $OUTPUT_FILE"
|
||||
echo "Summary: $TOTAL_TESTS tests, $TOTAL_FAILURES failures, $TOTAL_ERRORS errors, $TOTAL_SKIPPED skipped"
|
||||
echo "Processed $(echo "$SUITES_JSON" | jq 'length') test suite(s)"
|
||||
|
||||
|
|
@ -6,6 +6,12 @@
|
|||
],
|
||||
"settings": {
|
||||
"java.compile.nullAnalysis.mode": "automatic",
|
||||
"java.configuration.updateBuildConfiguration": "disabled"
|
||||
"java.configuration.updateBuildConfiguration": "disabled",
|
||||
"chat.mcp.discovery.enabled": {
|
||||
"claude-desktop": true,
|
||||
"windsurf": true,
|
||||
"cursor-global": true,
|
||||
"cursor-workspace": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,442 +0,0 @@
|
|||
{
|
||||
"summary": {
|
||||
"totalTests": 42,
|
||||
"totalFailures": 0,
|
||||
"totalErrors": 0,
|
||||
"totalSkipped": 2,
|
||||
"totalTime": 7.714999999999999
|
||||
},
|
||||
"suites": [
|
||||
{
|
||||
"name": "org.springframework.samples.petclinic.MySqlIntegrationTests",
|
||||
"tests": 2,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 2,
|
||||
"time": 0.001,
|
||||
"testCases": [
|
||||
{
|
||||
"name": "testFindAll",
|
||||
"classname": "org.springframework.samples.petclinic.MySqlIntegrationTests",
|
||||
"time": 0.0,
|
||||
"skipped": ""
|
||||
},
|
||||
{
|
||||
"name": "testOwnerDetails",
|
||||
"classname": "org.springframework.samples.petclinic.MySqlIntegrationTests",
|
||||
"time": 0.0,
|
||||
"skipped": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "org.springframework.samples.petclinic.PetClinicIntegrationTests",
|
||||
"tests": 2,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"time": 0.748,
|
||||
"testCases": [
|
||||
{
|
||||
"name": "testFindAll",
|
||||
"classname": "org.springframework.samples.petclinic.PetClinicIntegrationTests",
|
||||
"time": 0.014
|
||||
},
|
||||
{
|
||||
"name": "testOwnerDetails",
|
||||
"classname": "org.springframework.samples.petclinic.PetClinicIntegrationTests",
|
||||
"time": 0.051
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "org.springframework.samples.petclinic.PostgresIntegrationTests",
|
||||
"tests": 0,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"time": 0.215,
|
||||
"testCases": []
|
||||
},
|
||||
{
|
||||
"name": "org.springframework.samples.petclinic.model.ValidatorTests",
|
||||
"tests": 1,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"time": 0.013,
|
||||
"testCases": [
|
||||
{
|
||||
"name": "shouldNotValidateWhenFirstNameEmpty",
|
||||
"classname": "org.springframework.samples.petclinic.model.ValidatorTests",
|
||||
"time": 0.012
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "org.springframework.samples.petclinic.owner.OwnerControllerTests",
|
||||
"tests": 13,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"time": 0.488,
|
||||
"testCases": [
|
||||
{
|
||||
"name": "testProcessUpdateOwnerFormHasErrors",
|
||||
"classname": "org.springframework.samples.petclinic.owner.OwnerControllerTests",
|
||||
"time": 0.099
|
||||
},
|
||||
{
|
||||
"name": "testProcessCreationFormSuccess",
|
||||
"classname": "org.springframework.samples.petclinic.owner.OwnerControllerTests",
|
||||
"time": 0.005
|
||||
},
|
||||
{
|
||||
"name": "testInitFindForm",
|
||||
"classname": "org.springframework.samples.petclinic.owner.OwnerControllerTests",
|
||||
"time": 0.011
|
||||
},
|
||||
{
|
||||
"name": "testShowOwner",
|
||||
"classname": "org.springframework.samples.petclinic.owner.OwnerControllerTests",
|
||||
"time": 0.026
|
||||
},
|
||||
{
|
||||
"name": "testProcessUpdateOwnerFormWithIdMismatch",
|
||||
"classname": "org.springframework.samples.petclinic.owner.OwnerControllerTests",
|
||||
"time": 0.004
|
||||
},
|
||||
{
|
||||
"name": "testInitUpdateOwnerForm",
|
||||
"classname": "org.springframework.samples.petclinic.owner.OwnerControllerTests",
|
||||
"time": 0.009
|
||||
},
|
||||
{
|
||||
"name": "testInitCreationForm",
|
||||
"classname": "org.springframework.samples.petclinic.owner.OwnerControllerTests",
|
||||
"time": 0.008
|
||||
},
|
||||
{
|
||||
"name": "testProcessFindFormByLastName",
|
||||
"classname": "org.springframework.samples.petclinic.owner.OwnerControllerTests",
|
||||
"time": 0.004
|
||||
},
|
||||
{
|
||||
"name": "testProcessFindFormNoOwnersFound",
|
||||
"classname": "org.springframework.samples.petclinic.owner.OwnerControllerTests",
|
||||
"time": 0.014
|
||||
},
|
||||
{
|
||||
"name": "testProcessFindFormSuccess",
|
||||
"classname": "org.springframework.samples.petclinic.owner.OwnerControllerTests",
|
||||
"time": 0.036
|
||||
},
|
||||
{
|
||||
"name": "testProcessUpdateOwnerFormSuccess",
|
||||
"classname": "org.springframework.samples.petclinic.owner.OwnerControllerTests",
|
||||
"time": 0.004
|
||||
},
|
||||
{
|
||||
"name": "testProcessCreationFormHasErrors",
|
||||
"classname": "org.springframework.samples.petclinic.owner.OwnerControllerTests",
|
||||
"time": 0.007
|
||||
},
|
||||
{
|
||||
"name": "testProcessUpdateOwnerFormUnchangedSuccess",
|
||||
"classname": "org.springframework.samples.petclinic.owner.OwnerControllerTests",
|
||||
"time": 0.003
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "org.springframework.samples.petclinic.owner.PetControllerTests",
|
||||
"tests": 0,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"time": 0.383,
|
||||
"testCases": [
|
||||
{
|
||||
"name": "testProcessCreationFormSuccess",
|
||||
"classname": "org.springframework.samples.petclinic.owner.PetControllerTests",
|
||||
"time": 0.01
|
||||
},
|
||||
{
|
||||
"name": "testProcessUpdateFormSuccess",
|
||||
"classname": "org.springframework.samples.petclinic.owner.PetControllerTests",
|
||||
"time": 0.006
|
||||
},
|
||||
{
|
||||
"name": "testInitCreationForm",
|
||||
"classname": "org.springframework.samples.petclinic.owner.PetControllerTests",
|
||||
"time": 0.035
|
||||
},
|
||||
{
|
||||
"name": "testProcessUpdateFormWithInvalidBirthDate",
|
||||
"classname": "org.springframework.samples.petclinic.owner.PetControllerTests$ProcessUpdateFormHasErrors",
|
||||
"time": 0.018
|
||||
},
|
||||
{
|
||||
"name": "testProcessUpdateFormWithBlankName",
|
||||
"classname": "org.springframework.samples.petclinic.owner.PetControllerTests$ProcessUpdateFormHasErrors",
|
||||
"time": 0.013
|
||||
},
|
||||
{
|
||||
"name": "testProcessCreationFormWithBlankName",
|
||||
"classname": "org.springframework.samples.petclinic.owner.PetControllerTests$ProcessCreationFormHasErrors",
|
||||
"time": 0.015
|
||||
},
|
||||
{
|
||||
"name": "testInitUpdateForm",
|
||||
"classname": "org.springframework.samples.petclinic.owner.PetControllerTests$ProcessCreationFormHasErrors",
|
||||
"time": 0.012
|
||||
},
|
||||
{
|
||||
"name": "testProcessCreationFormWithMissingPetType",
|
||||
"classname": "org.springframework.samples.petclinic.owner.PetControllerTests$ProcessCreationFormHasErrors",
|
||||
"time": 0.012
|
||||
},
|
||||
{
|
||||
"name": "testProcessCreationFormWithDuplicateName",
|
||||
"classname": "org.springframework.samples.petclinic.owner.PetControllerTests$ProcessCreationFormHasErrors",
|
||||
"time": 0.011
|
||||
},
|
||||
{
|
||||
"name": "testProcessCreationFormWithInvalidBirthDate",
|
||||
"classname": "org.springframework.samples.petclinic.owner.PetControllerTests$ProcessCreationFormHasErrors",
|
||||
"time": 0.01
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "org.springframework.samples.petclinic.owner.PetTypeFormatterTests",
|
||||
"tests": 3,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"time": 0.006,
|
||||
"testCases": [
|
||||
{
|
||||
"name": "shouldThrowParseException",
|
||||
"classname": "org.springframework.samples.petclinic.owner.PetTypeFormatterTests",
|
||||
"time": 0.003
|
||||
},
|
||||
{
|
||||
"name": "testPrint",
|
||||
"classname": "org.springframework.samples.petclinic.owner.PetTypeFormatterTests",
|
||||
"time": 0.0
|
||||
},
|
||||
{
|
||||
"name": "shouldParse",
|
||||
"classname": "org.springframework.samples.petclinic.owner.PetTypeFormatterTests",
|
||||
"time": 0.001
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "org.springframework.samples.petclinic.owner.PetValidatorTests",
|
||||
"tests": 0,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"time": 0.019,
|
||||
"testCases": [
|
||||
{
|
||||
"name": "testValidate",
|
||||
"classname": "org.springframework.samples.petclinic.owner.PetValidatorTests",
|
||||
"time": 0.013
|
||||
},
|
||||
{
|
||||
"name": "testValidateWithInvalidPetName",
|
||||
"classname": "org.springframework.samples.petclinic.owner.PetValidatorTests$ValidateHasErrors",
|
||||
"time": 0.002
|
||||
},
|
||||
{
|
||||
"name": "testValidateWithInvalidPetType",
|
||||
"classname": "org.springframework.samples.petclinic.owner.PetValidatorTests$ValidateHasErrors",
|
||||
"time": 0.001
|
||||
},
|
||||
{
|
||||
"name": "testValidateWithInvalidBirthDate",
|
||||
"classname": "org.springframework.samples.petclinic.owner.PetValidatorTests$ValidateHasErrors",
|
||||
"time": 0.0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "org.springframework.samples.petclinic.owner.VisitControllerTests",
|
||||
"tests": 3,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"time": 0.159,
|
||||
"testCases": [
|
||||
{
|
||||
"name": "testProcessNewVisitFormHasErrors",
|
||||
"classname": "org.springframework.samples.petclinic.owner.VisitControllerTests",
|
||||
"time": 0.032
|
||||
},
|
||||
{
|
||||
"name": "testProcessNewVisitFormSuccess",
|
||||
"classname": "org.springframework.samples.petclinic.owner.VisitControllerTests",
|
||||
"time": 0.004
|
||||
},
|
||||
{
|
||||
"name": "testInitNewVisitForm",
|
||||
"classname": "org.springframework.samples.petclinic.owner.VisitControllerTests",
|
||||
"time": 0.006
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "org.springframework.samples.petclinic.service.ClinicServiceTests",
|
||||
"tests": 10,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"time": 1.948,
|
||||
"testCases": [
|
||||
{
|
||||
"name": "shouldFindVets",
|
||||
"classname": "org.springframework.samples.petclinic.service.ClinicServiceTests",
|
||||
"time": 0.087
|
||||
},
|
||||
{
|
||||
"name": "shouldFindOwnersByLastName",
|
||||
"classname": "org.springframework.samples.petclinic.service.ClinicServiceTests",
|
||||
"time": 0.056
|
||||
},
|
||||
{
|
||||
"name": "shouldAddNewVisitForPet",
|
||||
"classname": "org.springframework.samples.petclinic.service.ClinicServiceTests",
|
||||
"time": 0.023
|
||||
},
|
||||
{
|
||||
"name": "shouldUpdateOwner",
|
||||
"classname": "org.springframework.samples.petclinic.service.ClinicServiceTests",
|
||||
"time": 0.004
|
||||
},
|
||||
{
|
||||
"name": "shouldFindVisitsByPetId",
|
||||
"classname": "org.springframework.samples.petclinic.service.ClinicServiceTests",
|
||||
"time": 0.006
|
||||
},
|
||||
{
|
||||
"name": "shouldInsertPetIntoDatabaseAndGenerateId",
|
||||
"classname": "org.springframework.samples.petclinic.service.ClinicServiceTests",
|
||||
"time": 0.009
|
||||
},
|
||||
{
|
||||
"name": "shouldInsertOwner",
|
||||
"classname": "org.springframework.samples.petclinic.service.ClinicServiceTests",
|
||||
"time": 0.007
|
||||
},
|
||||
{
|
||||
"name": "shouldFindSingleOwnerWithPet",
|
||||
"classname": "org.springframework.samples.petclinic.service.ClinicServiceTests",
|
||||
"time": 0.004
|
||||
},
|
||||
{
|
||||
"name": "shouldUpdatePetName",
|
||||
"classname": "org.springframework.samples.petclinic.service.ClinicServiceTests",
|
||||
"time": 0.079
|
||||
},
|
||||
{
|
||||
"name": "shouldFindAllPetTypes",
|
||||
"classname": "org.springframework.samples.petclinic.service.ClinicServiceTests",
|
||||
"time": 0.014
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "org.springframework.samples.petclinic.system.CrashControllerIntegrationTests",
|
||||
"tests": 2,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"time": 1.074,
|
||||
"testCases": [
|
||||
{
|
||||
"name": "testTriggerExceptionHtml",
|
||||
"classname": "org.springframework.samples.petclinic.system.CrashControllerIntegrationTests",
|
||||
"time": 0.145
|
||||
},
|
||||
{
|
||||
"name": "testTriggerExceptionJson",
|
||||
"classname": "org.springframework.samples.petclinic.system.CrashControllerIntegrationTests",
|
||||
"time": 0.026
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "org.springframework.samples.petclinic.system.CrashControllerTests",
|
||||
"tests": 1,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"time": 0.004,
|
||||
"testCases": [
|
||||
{
|
||||
"name": "testTriggerException",
|
||||
"classname": "org.springframework.samples.petclinic.system.CrashControllerTests",
|
||||
"time": 0.003
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "org.springframework.samples.petclinic.system.I18nPropertiesSyncTest",
|
||||
"tests": 2,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"time": 0.025,
|
||||
"testCases": [
|
||||
{
|
||||
"name": "checkNonInternationalizedStrings",
|
||||
"classname": "org.springframework.samples.petclinic.system.I18nPropertiesSyncTest",
|
||||
"time": 0.021
|
||||
},
|
||||
{
|
||||
"name": "checkI18nPropertyFilesAreInSync",
|
||||
"classname": "org.springframework.samples.petclinic.system.I18nPropertiesSyncTest",
|
||||
"time": 0.003
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "org.springframework.samples.petclinic.vet.VetControllerTests",
|
||||
"tests": 2,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"time": 2.573,
|
||||
"testCases": [
|
||||
{
|
||||
"name": "testShowVetListHtml",
|
||||
"classname": "org.springframework.samples.petclinic.vet.VetControllerTests",
|
||||
"time": 0.559
|
||||
},
|
||||
{
|
||||
"name": "testShowResourcesVetList",
|
||||
"classname": "org.springframework.samples.petclinic.vet.VetControllerTests",
|
||||
"time": 0.072
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "org.springframework.samples.petclinic.vet.VetTests",
|
||||
"tests": 1,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"time": 0.059,
|
||||
"testCases": [
|
||||
{
|
||||
"name": "testSerialization",
|
||||
"classname": "org.springframework.samples.petclinic.vet.VetTests",
|
||||
"time": 0.059
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue