From 884bcf1e7c3b13c227b0b3e69acad638a6f2e09e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A1udia?= Date: Tue, 22 Sep 2026 11:48:58 +0100 Subject: [PATCH 1/9] docs: move and rewrite the image tagging guidance [OD-707] The tagging trade-off sat in an admonition below the tag list, four screens from where the decision is made, and framed the 1,000-tag cap as housekeeping. - Add "How tagging affects your findings" before the setup section, with the rolling-vs-per-release comparison and the consequences the old admonition omitted: dismissals, owners and SLA clocks reset on every new tag. - State what the cap actually does. Reaching it makes Codacy reject image tags it has not seen before, while existing tags carry on being scanned, so the release you just shipped silently stops being covered. Verified against ContainersDAO.scala:70-77 and reference.conf:115. - Add worked pipeline examples for both strategies. Every command was executed, not just written. - Correct two false bullets in the CI/CD section: nothing is detected or picked up automatically, you upload the image and tag you name. The new "#how-tagging-affects-your-findings" anchor is the target the Container Scanning designs link to from the manual setup caption and from all three tag-limit banners. Co-Authored-By: Claude Opus 5 --- docs/security/container-scanning.md | 89 +++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 5 deletions(-) diff --git a/docs/security/container-scanning.md b/docs/security/container-scanning.md index e278f3f2f0..a58df83a3a 100644 --- a/docs/security/container-scanning.md +++ b/docs/security/container-scanning.md @@ -22,6 +22,36 @@ The security tool analyzes your uploaded SBOM (Software Bill of Materials) files No manual action is required to trigger scans after the initial setup. +## How tagging affects your findings + +Codacy keeps a separate set of findings for every image tag you upload, and scans each of those tags once a day. The tag you upload to therefore decides how your findings behave over time, and it is the setup choice that is hardest to reverse: findings you have already accumulated stay on the tags that produced them. + +You have two options: + +- **One list, kept up to date.** Upload every build to the same tag, such as `prod`. Each upload replaces the last, so vulnerabilities you fix close automatically and your dismissals and owners carry over. +- **A separate list per release.** Upload each build to a new tag, such as `1.4.2`. Every release starts its own set of findings, so a vulnerability you fixed in your newest release stays open on the older ones. + +This changes what Codacy scans, not what you deploy. You can keep deploying from an immutable tag or a digest while pointing Codacy at a single rolling tag. + +| | One list, kept up to date | A separate list per release | +| --- | --- | --- | +| Findings across releases | The same findings are updated | A new set every release | +| A vulnerability you fixed | Closes automatically | Stays open on the older tags | +| Dismissals and owners | Carry over to the next upload | Reset on every release | +| SLA and MTTR | Measured across the life of the image | Restart with every release | +| Which build introduced a vulnerability | Not recorded | Recorded exactly | +| Image tags stored | One per image | One per release | + +Upload to a single tag unless you need a per-release record of what shipped. + +### What the image tag limit does + +Your organization can hold 1,000 image tags in total, counted across all your images. Uploading again to a tag Codacy already holds does not count against the limit, so an organization that uploads every image to a single rolling tag can stay under it indefinitely. + +Once you reach the limit, Codacy stops accepting image tags it has not seen before. The tags you already have keep being scanned every day, so the images list still looks healthy, but the release you just shipped is not scanned at all. The only signal is the error returned to your pipeline. + +To make room, delete the image tags for releases you no longer support. You can delete a single tag from the tag list of an image, or delete an image to remove all its tags at once. + ## Container scanning setup You can set up container scanning in one of two ways: by connecting your CI/CD pipeline or by manually uploading your image SBOM. Once configured, your image dependencies are scanned daily and results will appear in the Image card list. @@ -38,12 +68,58 @@ In order to do that, you need to: When CI/CD is configured: -- Images pushed through your pipeline are automatically detected -- New tags are picked up as they're published -- Scans are scheduled automatically +- Every pipeline run uploads an SBOM for the image and tag you name in the command +- Codacy scans each image tag you have uploaded once per day +- No manual action is required between releases This is the recommended setup for continuous coverage. +#### Example pipeline steps + +These examples use the [Codacy CLI v2](https://github.com/codacy/codacy-cli-v2), which generates the SBOM from your image and uploads it in a single command. They assume you have already set `CODACY_API_TOKEN` as described above. + +Install the CLI once per pipeline run: + +```bash +curl -fsSL https://raw.githubusercontent.com/codacy/codacy-cli-v2/main/codacy-cli.sh -o codacy-cli.sh +chmod +x codacy-cli.sh +./codacy-cli.sh init +``` + +`upload-sbom` reads a Codacy configuration from the working directory, which is what `init` creates. Without it the upload stops with `No configuration file was found, execute init command first.` + +To keep [one list of findings, kept up to date](#how-tagging-affects-your-findings), point your rolling tag at the image you just built and upload that: + +```bash +docker tag "${IMAGE_NAME}:${IMAGE_VERSION}" "${IMAGE_NAME}:prod" + +./codacy-cli.sh upload-sbom \ + -a "${CODACY_API_TOKEN}" \ + -p gh \ + -o "${ORGANIZATION_NAME}" \ + -r "${REPOSITORY_NAME}" \ + -e production \ + "${IMAGE_NAME}:prod" +``` + +The `docker tag` alias stays on the build machine and is never pushed. Without it the CLI resolves `prod` against your registry and scans whatever that tag points at there, rather than the image your pipeline just built. + +To keep [a separate list per release](#how-tagging-affects-your-findings), upload the release tag instead: + +```bash +./codacy-cli.sh upload-sbom \ + -a "${CODACY_API_TOKEN}" \ + -p gh \ + -o "${ORGANIZATION_NAME}" \ + -r "${REPOSITORY_NAME}" \ + -e production \ + "${IMAGE_NAME}:${IMAGE_VERSION}" +``` + +Every release adds an image tag, so delete the tags for releases you no longer support to stay under your organization limit. + +Replace `gh` with `gl` for GitLab or `bb` for Bitbucket. The `-r` and `-e` options are optional. + ### Manual upload You can also manually upload your container's Software Bill of Materials (SBOM) in CycloneDX or SPDX format. @@ -55,6 +131,8 @@ To manually upload an image SBOM, you need to: 2. Add the image tag; 3. Upload your SBOM file (environment and repository fields are optional). +Reuse a tag and each upload replaces the last. A new tag starts its own set of findings, so choose it with care: see [How tagging affects your findings](#how-tagging-affects-your-findings). + !!! note You can use the [Codacy CLI v2](https://github.com/codacy/codacy-cli-v2) to generate and upload your SBOM file to Codacy. @@ -86,8 +164,9 @@ For the image tags, the list is sorted by latest uploaded, and the information i Once a tag is scanned, you can click on the `check findings` link to access the findings page filtered by the respective results. !!! important - Findings are tied to specific image tags. To resolve a finding, "bump" the tag to a newer version if a fixed version exists (if not, a downgrade or an alternative image may be required). - For dynamic tags such as `latest`, Codacy will automatically close findings that are no longer present in the current analysis. If you use static tags, you will need to delete tags that are no longer used, as there's a limit of 1000 tags per organization. + Findings are tied to a specific image tag. To resolve one, upload an image where the dependency is fixed, usually by bumping it to a newer version. Where no fix exists, a downgrade or an alternative base image may be required. + +Whether that fix also closes the finding on your other tags depends on how you tag your images. See [How tagging affects your findings](#how-tagging-affects-your-findings). ## Deleting container image files from Codacy From 21424b73d61201e79cc843d6779914529ba8cf77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A1udia?= Date: Tue, 22 Sep 2026 11:53:16 +0100 Subject: [PATCH 2/9] docs: document the pipeline example placeholders like the DAST examples Match the convention in codacy-api/examples/uploading-dast-results.md: "Replace the placeholders with your own values" followed by a description list, with the Git provider values in a table. Only gh/gl/bb are listed. The DAST table also carries ghe/gle/bbe, but codacy-cli-v2 documents three values for -p (upload_sbom.go:54), so the enterprise rows are not copied across. Co-Authored-By: Claude Opus 5 --- docs/security/container-scanning.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/security/container-scanning.md b/docs/security/container-scanning.md index a58df83a3a..fbf76428dc 100644 --- a/docs/security/container-scanning.md +++ b/docs/security/container-scanning.md @@ -118,7 +118,22 @@ To keep [a separate list per release](#how-tagging-affects-your-findings), uploa Every release adds an image tag, so delete the tags for releases you no longer support to stay under your organization limit. -Replace `gh` with `gl` for GitLab or `bb` for Bitbucket. The `-r` and `-e` options are optional. +Replace the placeholders with your own values: + +- **CODACY_API_TOKEN:** [Account API token](../codacy-api/api-tokens.md#account-api-tokens) used to authenticate on Codacy, set as described in step 1 of the setup page. +- **`-p`:** Git provider hosting the organization, using one of the values in the table below. For example, `gh` for GitHub Cloud. + + | Value | Git provider | + |-------|-----------------| + | `gh` | GitHub Cloud | + | `gl` | GitLab Cloud | + | `bb` | Bitbucket Cloud | + +- **ORGANIZATION_NAME:** Name of the organization on the Git provider. For example, `codacy`. +- **IMAGE_NAME:** Name of the container image, without a tag. For example, `myapp`. +- **IMAGE_VERSION:** The tag your pipeline built, such as `1.4.2`. Only used by the per-release example. +- **REPOSITORY_NAME:** Optional. Name of the repository to associate the image with, so findings link back to it. +- **`-e`:** Optional. Environment where the image is deployed, such as `production`. It appears in the tag list. ### Manual upload You can also manually upload your container's Software Bill of Materials (SBOM) in CycloneDX or SPDX format. From d09d7acd2fe5acdf9bc66ac87c025f8a37618a5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A1udia?= Date: Tue, 22 Sep 2026 11:59:48 +0100 Subject: [PATCH 3/9] docs: add an API example page for container image SBOMs [OD-707] Mirrors codacy-api/examples/uploading-dast-results.md, so container scanning gets the same shape App scanning has: the feature page keeps the concepts, a "!!! note" links out to the API example. Covers uploadImageSbom, listImageTags and deleteImageTag. Delete is worth documenting now because it is the only way to stay under the 1,000-tag cap in CI today: the Cloud CLI's --delete --keep-latest is still an open PR. Contract read from the generated client (SbomService.ts:227-280, :286-345, :395-440) and the handler (SbomFilesHandler.uploadImageSbom): multipart sbom/imageName/tag with optional repositoryName and environment, 204 on success, 400 for the ContainerSbomError family. The cap rejection is not one of those errors, so it falls through to the generic handler rather than the 409 the swagger declares. The page tells readers to match on the message instead of the status. Co-Authored-By: Claude Opus 5 --- .../uploading-container-image-sboms.md | 105 ++++++++++++++++++ docs/security/container-scanning.md | 3 + mkdocs.yml | 1 + 3 files changed, 109 insertions(+) create mode 100644 docs/codacy-api/examples/uploading-container-image-sboms.md diff --git a/docs/codacy-api/examples/uploading-container-image-sboms.md b/docs/codacy-api/examples/uploading-container-image-sboms.md new file mode 100644 index 0000000000..2c2d28a485 --- /dev/null +++ b/docs/codacy-api/examples/uploading-container-image-sboms.md @@ -0,0 +1,105 @@ +--- +description: Instructions on how to upload container image SBOMs to Codacy using the API, and how to list and delete image tags. +--- + +# Uploading container image SBOMs to Codacy + +Codacy scans your container images for known vulnerabilities from an SBOM (Software Bill of Materials) that you upload. If your pipeline already produces an SBOM, or you generate one with a tool other than the [Codacy CLI v2](https://github.com/codacy/codacy-cli-v2), you can upload it directly through the API and monitor the results as findings under [Container scanning](../../security/container-scanning.md). + +Before you automate this, read [how tagging affects your findings](../../security/container-scanning.md#how-tagging-affects-your-findings). The tag you upload to decides whether Codacy keeps one set of findings for the image or starts a new set with every release, and it is the choice that is hardest to reverse. + +## Uploading an SBOM to Codacy + +1. Generate an SBOM of your container image in CycloneDX or SPDX format, using the tool of your choice. + +1. Upload it to Codacy using the API endpoint [uploadImageSbom](https://app.codacy.com/api/api-docs#uploadimagesbom): + + ```bash + curl -X POST https://app.codacy.com/api/v3/organizations///image-sboms \ + -H 'api-token: ' \ + -H 'Content-Type: multipart/form-data' \ + -F 'sbom=@' \ + -F 'imageName=' \ + -F 'tag=' + ``` + + A successful upload returns `204 No Content`. The image is scanned on the next nightly run, not immediately. + +Replace the placeholders with your own values: + +- **API_KEY:** [Account API token](../api-tokens.md#account-api-tokens) used to authenticate on the Codacy API. +- **GIT_PROVIDER:** Git provider hosting the organization, using one of the values in the table below. For example, `gh` for GitHub Cloud. + + | Value | Git provider | + |-------|-----------------| + | `gh` | GitHub Cloud | + | `gl` | GitLab Cloud | + | `bb` | Bitbucket Cloud | + +- **ORGANIZATION:** Name of the organization on the Git provider. For example, `codacy`. +- **SBOM_PATH:** Path to the file containing the SBOM. +- **IMAGE_NAME:** Name of the container image, without a tag. For example, `myapp`. +- **TAG:** Tag to record the findings against. For example, `prod` or `1.4.2`. + +The form also accepts two optional fields: + +- **repositoryName:** Repository to associate the image with, so findings link back to it. +- **environment:** Environment where the image is deployed, such as `production`. It appears in the tag list. + +!!! important + The tag you send in the `tag` field must match the tag recorded inside the SBOM, or the upload is rejected with `400 Bad Request` and the message `SBOM tag mismatch: expected , found `. Tools differ in where they write the image reference: Trivy writes the full `name:tag` into the SBOM's component name, while some other generators write the name and the tag separately. Check what your generator produces before scripting this. + +## Listing the image tags you have uploaded + +To retrieve the tags Codacy holds for an image, use the endpoint [listImageTags](https://app.codacy.com/api/api-docs#listimagetags): + +```bash +curl -X GET 'https://app.codacy.com/api/v3/organizations///images//tags?limit=100' \ + -H 'api-token: ' \ + -H 'Accept: application/json' +``` + +The endpoint returns at most 100 tags per request and paginates with a cursor. See [using pagination](../using-the-codacy-api.md#using-pagination) to retrieve the remaining pages. + +## Deleting an image tag + +Your organization can hold 1,000 image tags in total. Once you reach that limit, Codacy stops accepting image tags it has not seen before, so a pipeline that uploads a new tag on every release stops being scanned. To make room, delete the tags for releases you no longer support using [deleteImageTag](https://app.codacy.com/api/api-docs#deleteimagetag): + +```bash +curl -X DELETE https://app.codacy.com/api/v3/organizations///image-sboms//tags/ \ + -H 'api-token: ' +``` + +Deleting a tag removes its scan history and findings. To delete an image and all of its tags at once, call the same endpoint without the `/tags/` segment. + +!!! important + When your organization is at the limit, the upload fails with the message `Organization has reached the maximum limit of 1000 image SBOMs`. The tags you already have keep being scanned every day, so nothing else reports the problem. Match on the message rather than the status code, which is being made more specific. + +## Example: uploading an SBOM from your pipeline + +Use this example Bash script to upload an image SBOM to Codacy. This example can be adapted to fit your specific needs. + +The example script: + +1. Defines the [API token](../api-tokens.md#account-api-tokens) used to authenticate on the Codacy API. +1. Defines the image name and the tag to record the findings against. +1. Calls the endpoint [uploadImageSbom](https://app.codacy.com/api/api-docs#uploadimagesbom) to upload the SBOM. + +```bash +CODACY_API_TOKEN="" +GIT_PROVIDER="" # e.g., gh for GitHub +ORGANIZATION_NAME="" +IMAGE_NAME="" # e.g., myapp +IMAGE_TAG="prod" # one tag, reused every release +SBOM_FILE_PATH="sbom.cyclonedx.json" + +curl -X POST "https://app.codacy.com/api/v3/organizations/$GIT_PROVIDER/$ORGANIZATION_NAME/image-sboms" \ + -H "api-token: $CODACY_API_TOKEN" \ + -H "Content-Type: multipart/form-data" \ + -F "sbom=@$SBOM_FILE_PATH" \ + -F "imageName=$IMAGE_NAME" \ + -F "tag=$IMAGE_TAG" \ + -F "environment=production" +``` + +To record a separate set of findings per release, set `IMAGE_TAG` to the version your pipeline built instead, and delete the tags you no longer support so you stay under your organization limit. diff --git a/docs/security/container-scanning.md b/docs/security/container-scanning.md index fbf76428dc..df7d353470 100644 --- a/docs/security/container-scanning.md +++ b/docs/security/container-scanning.md @@ -78,6 +78,9 @@ This is the recommended setup for continuous coverage. These examples use the [Codacy CLI v2](https://github.com/codacy/codacy-cli-v2), which generates the SBOM from your image and uploads it in a single command. They assume you have already set `CODACY_API_TOKEN` as described above. +!!! note + Already generating SBOMs with another tool? [Upload them via the API.](../codacy-api/examples/uploading-container-image-sboms.md) + Install the CLI once per pipeline run: ```bash diff --git a/mkdocs.yml b/mkdocs.yml index 21eb964219..c136116800 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -774,6 +774,7 @@ nav: - codacy-api/examples/obtaining-current-issues-in-repositories.md - codacy-api/examples/identifying-commits-without-coverage-data.md - codacy-api/examples/uploading-dast-results.md + - codacy-api/examples/uploading-container-image-sboms.md - codacy-api/examples/triggering-dast-scans.md - Codacy CLIs: - codacy-analysis-cli/index.md From 7110b0a7bea6f0970b75cf95136206166d4ffc82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A1udia?= Date: Tue, 22 Sep 2026 12:00:35 +0100 Subject: [PATCH 4/9] docs: fix Vale spelling and wordiness on the SBOM API example Co-Authored-By: Claude Opus 5 --- docs/codacy-api/examples/uploading-container-image-sboms.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/codacy-api/examples/uploading-container-image-sboms.md b/docs/codacy-api/examples/uploading-container-image-sboms.md index 2c2d28a485..e2c974ba07 100644 --- a/docs/codacy-api/examples/uploading-container-image-sboms.md +++ b/docs/codacy-api/examples/uploading-container-image-sboms.md @@ -47,7 +47,7 @@ The form also accepts two optional fields: - **environment:** Environment where the image is deployed, such as `production`. It appears in the tag list. !!! important - The tag you send in the `tag` field must match the tag recorded inside the SBOM, or the upload is rejected with `400 Bad Request` and the message `SBOM tag mismatch: expected , found `. Tools differ in where they write the image reference: Trivy writes the full `name:tag` into the SBOM's component name, while some other generators write the name and the tag separately. Check what your generator produces before scripting this. + The tag you send in the `tag` field must match the tag recorded inside the SBOM, or the upload is rejected with `400 Bad Request` and the message `SBOM tag mismatch: expected , found `. Tools differ in where they write the image reference: Trivy writes the full `name:tag` into the component name inside the SBOM, while some other generators write the name and the tag in different fields. Check what your generator produces before scripting this. ## Listing the image tags you have uploaded @@ -70,7 +70,7 @@ curl -X DELETE https://app.codacy.com/api/v3/organizations//' ``` -Deleting a tag removes its scan history and findings. To delete an image and all of its tags at once, call the same endpoint without the `/tags/` segment. +Deleting a tag removes its scan history and findings. To delete an image and all its tags at once, call the same endpoint without the `/tags/` segment. !!! important When your organization is at the limit, the upload fails with the message `Organization has reached the maximum limit of 1000 image SBOMs`. The tags you already have keep being scanned every day, so nothing else reports the problem. Match on the message rather than the status code, which is being made more specific. From e31d57430c13106abc688a5c58ae230a250f617c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A1udia?= Date: Tue, 22 Sep 2026 12:08:05 +0100 Subject: [PATCH 5/9] docs: document the Cloud CLI container image commands [OD-707] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit codacy-cloud-cli#49, #50 and #52 have merged and ship as 1.12.0 in the pending release PR #54, so the commands are real and the docs no longer have to route everything through the API. codacy-cloud-cli/index.md gains two sections: - "Manage container images" — images, image, --tag, --upload, --delete, and the 100/1000 limit defaults. - "Keep container image tags under the organization limit" — --delete --keep-latest, --dry-run, the JSON shape, and the per-image vs organization-wide caveat the command warns about. container-scanning.md's per-release example now runs the cleanup before the upload, which is the order the backend forces: at the cap the upload is rejected, so cleaning up afterwards strands the organization there. Surface read from src/commands/image.ts and images.ts on origin/main, not from the changeset prose. Token handling confirmed at src/utils/auth.ts:171. Co-Authored-By: Claude Opus 5 --- .../uploading-container-image-sboms.md | 3 + docs/codacy-cloud-cli/index.md | 61 +++++++++++++++++++ docs/security/container-scanning.md | 14 ++++- 3 files changed, 75 insertions(+), 3 deletions(-) diff --git a/docs/codacy-api/examples/uploading-container-image-sboms.md b/docs/codacy-api/examples/uploading-container-image-sboms.md index e2c974ba07..7eaa007a1e 100644 --- a/docs/codacy-api/examples/uploading-container-image-sboms.md +++ b/docs/codacy-api/examples/uploading-container-image-sboms.md @@ -72,6 +72,9 @@ curl -X DELETE https://app.codacy.com/api/v3/organizations//` segment. +!!! tip + To prune tags on a schedule rather than one at a time, the [Codacy Cloud CLI](../../codacy-cloud-cli/index.md#keep-latest) does this in one command: `codacy image gh my-org my-service --delete --keep-latest 10`. + !!! important When your organization is at the limit, the upload fails with the message `Organization has reached the maximum limit of 1000 image SBOMs`. The tags you already have keep being scanned every day, so nothing else reports the problem. Match on the message rather than the status code, which is being made more specific. diff --git a/docs/codacy-cloud-cli/index.md b/docs/codacy-cloud-cli/index.md index daa88d2d16..69a3cbab26 100644 --- a/docs/codacy-cloud-cli/index.md +++ b/docs/codacy-cloud-cli/index.md @@ -168,6 +168,67 @@ This information is also included when using `--output json`. !!! note Not every advisory lists specific affected functions — this section only appears when Codacy has identified them. +### Manage container images {: id="manage-container-images"} + +List the container images with SBOMs uploaded to an organization, inspect an image's tags, upload an SBOM, and delete tags you no longer need. These commands require an [account API token](../codacy-api/api-tokens.md#account-api-tokens), because they read organization-level data. + +!!! note + Available from Codacy Cloud CLI 1.12.0. + +```bash +# List the images in an organization, with their latest tag +codacy images gh my-org + +# List an image's tags, with environment, repository, and analysis dates +codacy image gh my-org my-service + +# Show a single tag +codacy image gh my-org my-service --tag 1.2.3 +``` + +Both commands return 100 results by default. Use `--limit` to raise that, up to 1000. + +Upload an SBOM your pipeline already produced, in SPDX or CycloneDX format: + +```bash +codacy image gh my-org my-service --tag 1.2.3 --upload ./sbom.json + +# Record where the image runs and which repository it belongs to +codacy image gh my-org my-service --tag prod --upload ./sbom.json \ + --environment production --repository my-repo +``` + +The file is checked before the request, so a wrong path or an empty file fails immediately. + +Delete a single tag, or the whole image: + +```bash +# One tag +codacy image gh my-org my-service --tag 1.2.3 --delete + +# Every tag of the image +codacy image gh my-org my-service --delete +``` + +### Keep container image tags under the organization limit {: id="keep-latest"} + +An organization can hold 1000 image tags in total. Once it reaches that limit, Codacy stops accepting image tags it has not seen before, so a pipeline that uploads a new tag on every release stops being scanned. See [how tagging affects your findings](../security/container-scanning.md#how-tagging-affects-your-findings). + +`--keep-latest` deletes the older tags of an image, keeping the most recently uploaded ones. Run it as the cleanup step of a release pipeline, **before** the upload, so that the space is freed before the new tag needs it: + +```bash +# Show what would be deleted, delete nothing +codacy image gh my-org my-service --delete --keep-latest 10 --dry-run + +# Delete, without prompting — for CI +codacy image gh my-org my-service --delete --keep-latest 10 --skip-confirmation +``` + +Deletes run one at a time and continue past failures, so a partial cleanup still frees space. Under `--output json` the command emits a single object listing the tags in `deleted` and the ones that failed in `failures`, and exits non-zero if any tag failed. + +!!! important + The organization limit counts image-and-tag pairs, while `--keep-latest` applies per image. Keeping 10 tags across 212 images is 2120 tags against a limit of 1000. The command warns when the number you ask for would exceed the limit across every image in the organization, and says what the limit allows per image instead. + ### List and filter pull requests ```bash diff --git a/docs/security/container-scanning.md b/docs/security/container-scanning.md index df7d353470..db58765ec7 100644 --- a/docs/security/container-scanning.md +++ b/docs/security/container-scanning.md @@ -50,7 +50,7 @@ Your organization can hold 1,000 image tags in total, counted across all your im Once you reach the limit, Codacy stops accepting image tags it has not seen before. The tags you already have keep being scanned every day, so the images list still looks healthy, but the release you just shipped is not scanned at all. The only signal is the error returned to your pipeline. -To make room, delete the image tags for releases you no longer support. You can delete a single tag from the tag list of an image, or delete an image to remove all its tags at once. +To make room, delete the image tags for releases you no longer support. You can delete a single tag from the tag list of an image, or delete an image to remove all its tags at once. To prune tags automatically as part of a pipeline, use the [Codacy Cloud CLI](../codacy-cloud-cli/index.md#keep-latest). ## Container scanning setup @@ -107,9 +107,15 @@ docker tag "${IMAGE_NAME}:${IMAGE_VERSION}" "${IMAGE_NAME}:prod" The `docker tag` alias stays on the build machine and is never pushed. Without it the CLI resolves `prod` against your registry and scans whatever that tag points at there, rather than the image your pipeline just built. -To keep [a separate list per release](#how-tagging-affects-your-findings), upload the release tag instead: +To keep [a separate list per release](#how-tagging-affects-your-findings), delete the tags you no longer need and then upload the release tag: ```bash +npm install -g "@codacy/codacy-cloud-cli" + +# Keep the 10 most recently uploaded tags, delete the rest +codacy image gh "${ORGANIZATION_NAME}" "${IMAGE_NAME}" \ + --delete --keep-latest 10 --skip-confirmation + ./codacy-cli.sh upload-sbom \ -a "${CODACY_API_TOKEN}" \ -p gh \ @@ -119,7 +125,9 @@ To keep [a separate list per release](#how-tagging-affects-your-findings), uploa "${IMAGE_NAME}:${IMAGE_VERSION}" ``` -Every release adds an image tag, so delete the tags for releases you no longer support to stay under your organization limit. +Every release adds an image tag, so clean up on every run to stay under your organization limit. Put the cleanup **before** the upload: at the limit the upload is rejected, so a pipeline that uploads first and cleans up later stops making progress. Add `--dry-run` to see which tags would go without deleting anything. + +The [Codacy Cloud CLI](../codacy-cloud-cli/index.md#keep-latest) reads the same `CODACY_API_TOKEN` you set in step 1, and needs version 1.12.0 or later. It can also upload the SBOM itself with `--upload`, if your pipeline already produces one. Replace the placeholders with your own values: From beb2c7d7e90064216671d163dca47b4eb22cbd34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A1udia?= Date: Tue, 22 Sep 2026 14:17:04 +0100 Subject: [PATCH 6/9] docs: document the Cloud CLI upload path and how to recover an image [OD-707] Two gaps, both raised against the bfi-finance thread in #product-help: that organization is carrying ~1.5M container findings on ~970 of its 1,000 image tags, and nothing in the docs told them what to do about it. "If your pipeline already produces an SBOM" adds the Cloud CLI upload for both strategies, which the mockups draw as a tab but this page only mentioned in passing. No docker tag alias is needed there: --upload attaches a file to a tag and never resolves the image. "Reducing findings on an image that already has many tags" is the recovery path. Switching the tag a pipeline uploads to does nothing on its own, because the tags already stored keep their findings and keep being scanned nightly. Deleting a tag is what removes them: verified through RemovedImageTag -> RemovedImageTagWriterStream -> itemsDAO.deleteContainerScanItemsByImageTag, which deletes rather than closes, and does so asynchronously. Both new sections carry a token pointer, so the snippet harness is clean on every block: the recovery reader arrives from a support conversation rather than from step 1 of the setup page. Co-Authored-By: Claude Opus 5 --- docs/security/container-scanning.md | 74 ++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/docs/security/container-scanning.md b/docs/security/container-scanning.md index db58765ec7..0343ed0f8c 100644 --- a/docs/security/container-scanning.md +++ b/docs/security/container-scanning.md @@ -52,6 +52,43 @@ Once you reach the limit, Codacy stops accepting image tags it has not seen befo To make room, delete the image tags for releases you no longer support. You can delete a single tag from the tag list of an image, or delete an image to remove all its tags at once. To prune tags automatically as part of a pipeline, use the [Codacy Cloud CLI](../codacy-cloud-cli/index.md#keep-latest). +### Reducing findings on an image that already has many tags + +Changing the tag your pipeline uploads to does not change the findings you already have. The tags you accumulated keep their own findings, and Codacy keeps scanning every one of them every night, so the finding count stays where it is until you remove the tags behind it. + +To bring an image back under control: + +1. Point your pipeline at a single tag, following [one list, kept up to date](#how-tagging-affects-your-findings). New releases now update one set of findings instead of starting another. + +1. List the tags Codacy holds for the image, so you know what you are working with. The [Codacy Cloud CLI](../codacy-cloud-cli/index.md#manage-container-images) needs an [account API token](../codacy-api/api-tokens.md#account-api-tokens), from `codacy login` or the `CODACY_API_TOKEN` environment variable: + + ```bash + export CODACY_API_TOKEN="" + + codacy image gh "${ORGANIZATION_NAME}" "${IMAGE_NAME}" --limit 1000 + ``` + +1. Check what a cleanup would remove, without removing anything: + + ```bash + codacy image gh "${ORGANIZATION_NAME}" "${IMAGE_NAME}" \ + --delete --keep-latest 10 --dry-run + ``` + +1. Delete the tags for releases you no longer support: + + ```bash + codacy image gh "${ORGANIZATION_NAME}" "${IMAGE_NAME}" \ + --delete --keep-latest 10 + ``` + +Deleting a tag deletes the findings recorded against it, along with its scan history. The finding counts drop once the deletions have been processed, which happens shortly after the command returns rather than immediately. Keep the tags for the releases you still run in production, since those are the findings that describe something you are actually exposed to. + +!!! important + Deleting an image tag cannot be undone. Start with `--dry-run`, and keep the tags for every release you still support. + +Tags accumulate per image, so find the images responsible before you start. `codacy images gh ` lists every image in the organization, and usually a small number of them account for most of the tags. + ## Container scanning setup You can set up container scanning in one of two ways: by connecting your CI/CD pipeline or by manually uploading your image SBOM. Once configured, your image dependencies are scanned daily and results will appear in the Image card list. @@ -127,7 +164,7 @@ codacy image gh "${ORGANIZATION_NAME}" "${IMAGE_NAME}" \ Every release adds an image tag, so clean up on every run to stay under your organization limit. Put the cleanup **before** the upload: at the limit the upload is rejected, so a pipeline that uploads first and cleans up later stops making progress. Add `--dry-run` to see which tags would go without deleting anything. -The [Codacy Cloud CLI](../codacy-cloud-cli/index.md#keep-latest) reads the same `CODACY_API_TOKEN` you set in step 1, and needs version 1.12.0 or later. It can also upload the SBOM itself with `--upload`, if your pipeline already produces one. +The [Codacy Cloud CLI](../codacy-cloud-cli/index.md#keep-latest) reads the same `CODACY_API_TOKEN` you set in step 1, and needs version 1.12.0 or later. Replace the placeholders with your own values: @@ -146,6 +183,41 @@ Replace the placeholders with your own values: - **REPOSITORY_NAME:** Optional. Name of the repository to associate the image with, so findings link back to it. - **`-e`:** Optional. Environment where the image is deployed, such as `production`. It appears in the tag list. +#### If your pipeline already produces an SBOM + +The examples above use the Codacy CLI v2 because it generates the SBOM and uploads it in one step. If your pipeline already produces an SBOM in CycloneDX or SPDX format, upload that file directly with the [Codacy Cloud CLI](../codacy-cloud-cli/index.md#manage-container-images) instead. It reads the same `CODACY_API_TOKEN` you set in step 1, and needs version 1.12.0 or later. + +```bash +npm install -g "@codacy/codacy-cloud-cli" + +# Uses the CODACY_API_TOKEN you set in step 1. +``` + +To keep one list of findings, upload every release to the same tag: + +```bash +codacy image gh "${ORGANIZATION_NAME}" "${IMAGE_NAME}" \ + --tag prod \ + --upload "${SBOM_FILE}" \ + --environment production \ + --repository "${REPOSITORY_NAME}" +``` + +To keep a separate list per release, clean up first and then upload under the release tag: + +```bash +codacy image gh "${ORGANIZATION_NAME}" "${IMAGE_NAME}" \ + --delete --keep-latest 10 --skip-confirmation + +codacy image gh "${ORGANIZATION_NAME}" "${IMAGE_NAME}" \ + --tag "${IMAGE_VERSION}" \ + --upload "${SBOM_FILE}" \ + --environment production \ + --repository "${REPOSITORY_NAME}" +``` + +This path never resolves the image itself, so it needs no `docker tag` alias: it attaches the SBOM file you name to the tag you name. + ### Manual upload You can also manually upload your container's Software Bill of Materials (SBOM) in CycloneDX or SPDX format. From 7c3ce6e935b6ff8f252b21600da26cdf3de2df42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A1udia?= Date: Tue, 22 Sep 2026 14:23:26 +0100 Subject: [PATCH 7/9] docs: make the changed lines pass Vale MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Vale blocks in CI — it runs through reviewdog against the diff, so the lines this PR adds have to be clean even though the files around them are not. I had left the contraction errors on the grounds that Vale is advisory, which docs-edit says but CI does not. .vale.ini settles the underlying conflict with voice.md: the "do not" style is explicitly scoped to the agent instruction files, and docs/** is expected to contract. Also replaces an inline `codacy images gh ` with a fenced block. IgnoredScopes covers code, but the token inside the span still tripped Vale.Terms and Vale.Spelling in CI, and the fenced form matches the rest of the section anyway. Co-Authored-By: Claude Opus 5 --- .../uploading-container-image-sboms.md | 4 ++-- docs/codacy-cloud-cli/index.md | 2 +- docs/security/container-scanning.md | 18 +++++++++++------- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/docs/codacy-api/examples/uploading-container-image-sboms.md b/docs/codacy-api/examples/uploading-container-image-sboms.md index 7eaa007a1e..34aa2d5e95 100644 --- a/docs/codacy-api/examples/uploading-container-image-sboms.md +++ b/docs/codacy-api/examples/uploading-container-image-sboms.md @@ -6,7 +6,7 @@ description: Instructions on how to upload container image SBOMs to Codacy using Codacy scans your container images for known vulnerabilities from an SBOM (Software Bill of Materials) that you upload. If your pipeline already produces an SBOM, or you generate one with a tool other than the [Codacy CLI v2](https://github.com/codacy/codacy-cli-v2), you can upload it directly through the API and monitor the results as findings under [Container scanning](../../security/container-scanning.md). -Before you automate this, read [how tagging affects your findings](../../security/container-scanning.md#how-tagging-affects-your-findings). The tag you upload to decides whether Codacy keeps one set of findings for the image or starts a new set with every release, and it is the choice that is hardest to reverse. +Before you automate this, read [how tagging affects your findings](../../security/container-scanning.md#how-tagging-affects-your-findings). The tag you upload to decides whether Codacy keeps one set of findings for the image or starts a new set with every release, and it's the choice that's hardest to reverse. ## Uploading an SBOM to Codacy @@ -63,7 +63,7 @@ The endpoint returns at most 100 tags per request and paginates with a cursor. S ## Deleting an image tag -Your organization can hold 1,000 image tags in total. Once you reach that limit, Codacy stops accepting image tags it has not seen before, so a pipeline that uploads a new tag on every release stops being scanned. To make room, delete the tags for releases you no longer support using [deleteImageTag](https://app.codacy.com/api/api-docs#deleteimagetag): +Your organization can hold 1,000 image tags in total. Once you reach that limit, Codacy stops accepting image tags it hasn't seen before, so a pipeline that uploads a new tag on every release stops being scanned. To make room, delete the tags for releases you no longer support using [deleteImageTag](https://app.codacy.com/api/api-docs#deleteimagetag): ```bash curl -X DELETE https://app.codacy.com/api/v3/organizations///image-sboms//tags/ \ diff --git a/docs/codacy-cloud-cli/index.md b/docs/codacy-cloud-cli/index.md index 69a3cbab26..e25910e55f 100644 --- a/docs/codacy-cloud-cli/index.md +++ b/docs/codacy-cloud-cli/index.md @@ -212,7 +212,7 @@ codacy image gh my-org my-service --delete ### Keep container image tags under the organization limit {: id="keep-latest"} -An organization can hold 1000 image tags in total. Once it reaches that limit, Codacy stops accepting image tags it has not seen before, so a pipeline that uploads a new tag on every release stops being scanned. See [how tagging affects your findings](../security/container-scanning.md#how-tagging-affects-your-findings). +An organization can hold 1000 image tags in total. Once it reaches that limit, Codacy stops accepting image tags it hasn't seen before, so a pipeline that uploads a new tag on every release stops being scanned. See [how tagging affects your findings](../security/container-scanning.md#how-tagging-affects-your-findings). `--keep-latest` deletes the older tags of an image, keeping the most recently uploaded ones. Run it as the cleanup step of a release pipeline, **before** the upload, so that the space is freed before the new tag needs it: diff --git a/docs/security/container-scanning.md b/docs/security/container-scanning.md index 0343ed0f8c..15887ad2d2 100644 --- a/docs/security/container-scanning.md +++ b/docs/security/container-scanning.md @@ -24,7 +24,7 @@ No manual action is required to trigger scans after the initial setup. ## How tagging affects your findings -Codacy keeps a separate set of findings for every image tag you upload, and scans each of those tags once a day. The tag you upload to therefore decides how your findings behave over time, and it is the setup choice that is hardest to reverse: findings you have already accumulated stay on the tags that produced them. +Codacy keeps a separate set of findings for every image tag you upload, and scans each of those tags once a day. The tag you upload to therefore decides how your findings behave over time, and it's the setup choice that's hardest to reverse: findings you have already accumulated stay on the tags that produced them. You have two options: @@ -46,15 +46,15 @@ Upload to a single tag unless you need a per-release record of what shipped. ### What the image tag limit does -Your organization can hold 1,000 image tags in total, counted across all your images. Uploading again to a tag Codacy already holds does not count against the limit, so an organization that uploads every image to a single rolling tag can stay under it indefinitely. +Your organization can hold 1,000 image tags in total, counted across all your images. Uploading again to a tag Codacy already holds doesn't count against the limit, so an organization that uploads every image to a single rolling tag can stay under it indefinitely. -Once you reach the limit, Codacy stops accepting image tags it has not seen before. The tags you already have keep being scanned every day, so the images list still looks healthy, but the release you just shipped is not scanned at all. The only signal is the error returned to your pipeline. +Once you reach the limit, Codacy stops accepting image tags it hasn't seen before. The tags you already have keep being scanned every day, so the images list still looks healthy, but the release you just shipped isn't scanned at all. The only signal is the error returned to your pipeline. To make room, delete the image tags for releases you no longer support. You can delete a single tag from the tag list of an image, or delete an image to remove all its tags at once. To prune tags automatically as part of a pipeline, use the [Codacy Cloud CLI](../codacy-cloud-cli/index.md#keep-latest). ### Reducing findings on an image that already has many tags -Changing the tag your pipeline uploads to does not change the findings you already have. The tags you accumulated keep their own findings, and Codacy keeps scanning every one of them every night, so the finding count stays where it is until you remove the tags behind it. +Changing the tag your pipeline uploads to doesn't change the findings you already have. The tags you accumulated keep their own findings, and Codacy keeps scanning every one of them every night, so the finding count stays put until you remove the tags behind it. To bring an image back under control: @@ -85,9 +85,13 @@ To bring an image back under control: Deleting a tag deletes the findings recorded against it, along with its scan history. The finding counts drop once the deletions have been processed, which happens shortly after the command returns rather than immediately. Keep the tags for the releases you still run in production, since those are the findings that describe something you are actually exposed to. !!! important - Deleting an image tag cannot be undone. Start with `--dry-run`, and keep the tags for every release you still support. + Deleting an image tag can't be undone. Start with `--dry-run`, and keep the tags for every release you still support. -Tags accumulate per image, so find the images responsible before you start. `codacy images gh ` lists every image in the organization, and usually a small number of them account for most of the tags. +Tags accumulate per image, so find the images responsible before you start. Usually a small number of them account for most of the tags: + +```bash +codacy images gh "${ORGANIZATION_NAME}" +``` ## Container scanning setup @@ -162,7 +166,7 @@ codacy image gh "${ORGANIZATION_NAME}" "${IMAGE_NAME}" \ "${IMAGE_NAME}:${IMAGE_VERSION}" ``` -Every release adds an image tag, so clean up on every run to stay under your organization limit. Put the cleanup **before** the upload: at the limit the upload is rejected, so a pipeline that uploads first and cleans up later stops making progress. Add `--dry-run` to see which tags would go without deleting anything. +Every release adds an image tag, so clean up on every run to stay under your organization limit. Put the cleanup **before** the upload: at the limit the upload is rejected, so a pipeline that uploads first and cleans up later can't make progress. Add `--dry-run` to see which tags would go without deleting anything. The [Codacy Cloud CLI](../codacy-cloud-cli/index.md#keep-latest) reads the same `CODACY_API_TOKEN` you set in step 1, and needs version 1.12.0 or later. From be7fcd05d2631e9fb967b57304176d3103314e35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A1udia?= Date: Tue, 22 Sep 2026 14:31:02 +0100 Subject: [PATCH 8/9] docs: give each tagging option a link to its own pipeline example Both options pointed at #example-pipeline-steps, which covers both, so neither bullet led anywhere specific. The two examples are now sibling #### headings with pinned ids, and each option links to its own. Co-Authored-By: Claude Opus 5 --- docs/security/container-scanning.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/docs/security/container-scanning.md b/docs/security/container-scanning.md index 15887ad2d2..9b54bbaefa 100644 --- a/docs/security/container-scanning.md +++ b/docs/security/container-scanning.md @@ -28,8 +28,8 @@ Codacy keeps a separate set of findings for every image tag you upload, and scan You have two options: -- **One list, kept up to date.** Upload every build to the same tag, such as `prod`. Each upload replaces the last, so vulnerabilities you fix close automatically and your dismissals and owners carry over. -- **A separate list per release.** Upload each build to a new tag, such as `1.4.2`. Every release starts its own set of findings, so a vulnerability you fixed in your newest release stays open on the older ones. +- **One list, kept up to date.** Upload every build to the same tag, such as `prod`. Each upload replaces the last, so vulnerabilities you fix close automatically and your dismissals and owners carry over. [See the pipeline example](#example-one-list). +- **A separate list per release.** Upload each build to a new tag, such as `1.4.2`. Every release starts its own set of findings, so a vulnerability you fixed in your newest release stays open on the older ones. [See the pipeline example](#example-per-release). This changes what Codacy scans, not what you deploy. You can keep deploying from an immutable tag or a digest while pointing Codacy at a single rolling tag. @@ -132,7 +132,9 @@ chmod +x codacy-cli.sh `upload-sbom` reads a Codacy configuration from the working directory, which is what `init` creates. Without it the upload stops with `No configuration file was found, execute init command first.` -To keep [one list of findings, kept up to date](#how-tagging-affects-your-findings), point your rolling tag at the image you just built and upload that: +#### Example: one list, kept up to date {: id="example-one-list"} + +For [one list of findings, kept up to date](#how-tagging-affects-your-findings), point your rolling tag at the image you just built and upload that: ```bash docker tag "${IMAGE_NAME}:${IMAGE_VERSION}" "${IMAGE_NAME}:prod" @@ -148,7 +150,9 @@ docker tag "${IMAGE_NAME}:${IMAGE_VERSION}" "${IMAGE_NAME}:prod" The `docker tag` alias stays on the build machine and is never pushed. Without it the CLI resolves `prod` against your registry and scans whatever that tag points at there, rather than the image your pipeline just built. -To keep [a separate list per release](#how-tagging-affects-your-findings), delete the tags you no longer need and then upload the release tag: +#### Example: a separate list per release {: id="example-per-release"} + +For [a separate list per release](#how-tagging-affects-your-findings), delete the tags you no longer need and then upload the release tag: ```bash npm install -g "@codacy/codacy-cloud-cli" @@ -170,7 +174,7 @@ Every release adds an image tag, so clean up on every run to stay under your org The [Codacy Cloud CLI](../codacy-cloud-cli/index.md#keep-latest) reads the same `CODACY_API_TOKEN` you set in step 1, and needs version 1.12.0 or later. -Replace the placeholders with your own values: +Both examples use these placeholders. Replace them with your own values: - **CODACY_API_TOKEN:** [Account API token](../codacy-api/api-tokens.md#account-api-tokens) used to authenticate on Codacy, set as described in step 1 of the setup page. - **`-p`:** Git provider hosting the organization, using one of the values in the table below. For example, `gh` for GitHub Cloud. From e99c7257630a037cdee2967776d0643559a78c09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A1udia?= Date: Tue, 22 Sep 2026 14:53:25 +0100 Subject: [PATCH 9/9] docs: require Codacy Cloud CLI 1.12.1 for the container image commands 1.12.0 shipped the commands but 404s on any namespaced image name, which is the usual shape. codacy-cloud-cli#55 fixes the path encoding and publishes as 1.12.1 in the pending release PR #56, so that is the floor the examples here need. Co-Authored-By: Claude Opus 5 --- docs/codacy-cloud-cli/index.md | 2 +- docs/security/container-scanning.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/codacy-cloud-cli/index.md b/docs/codacy-cloud-cli/index.md index e25910e55f..349bd23df5 100644 --- a/docs/codacy-cloud-cli/index.md +++ b/docs/codacy-cloud-cli/index.md @@ -173,7 +173,7 @@ This information is also included when using `--output json`. List the container images with SBOMs uploaded to an organization, inspect an image's tags, upload an SBOM, and delete tags you no longer need. These commands require an [account API token](../codacy-api/api-tokens.md#account-api-tokens), because they read organization-level data. !!! note - Available from Codacy Cloud CLI 1.12.0. + Available from Codacy Cloud CLI 1.12.1. ```bash # List the images in an organization, with their latest tag diff --git a/docs/security/container-scanning.md b/docs/security/container-scanning.md index 9b54bbaefa..c41d96eb5b 100644 --- a/docs/security/container-scanning.md +++ b/docs/security/container-scanning.md @@ -172,7 +172,7 @@ codacy image gh "${ORGANIZATION_NAME}" "${IMAGE_NAME}" \ Every release adds an image tag, so clean up on every run to stay under your organization limit. Put the cleanup **before** the upload: at the limit the upload is rejected, so a pipeline that uploads first and cleans up later can't make progress. Add `--dry-run` to see which tags would go without deleting anything. -The [Codacy Cloud CLI](../codacy-cloud-cli/index.md#keep-latest) reads the same `CODACY_API_TOKEN` you set in step 1, and needs version 1.12.0 or later. +The [Codacy Cloud CLI](../codacy-cloud-cli/index.md#keep-latest) reads the same `CODACY_API_TOKEN` you set in step 1, and needs version 1.12.1 or later. Both examples use these placeholders. Replace them with your own values: @@ -193,7 +193,7 @@ Both examples use these placeholders. Replace them with your own values: #### If your pipeline already produces an SBOM -The examples above use the Codacy CLI v2 because it generates the SBOM and uploads it in one step. If your pipeline already produces an SBOM in CycloneDX or SPDX format, upload that file directly with the [Codacy Cloud CLI](../codacy-cloud-cli/index.md#manage-container-images) instead. It reads the same `CODACY_API_TOKEN` you set in step 1, and needs version 1.12.0 or later. +The examples above use the Codacy CLI v2 because it generates the SBOM and uploads it in one step. If your pipeline already produces an SBOM in CycloneDX or SPDX format, upload that file directly with the [Codacy Cloud CLI](../codacy-cloud-cli/index.md#manage-container-images) instead. It reads the same `CODACY_API_TOKEN` you set in step 1, and needs version 1.12.1 or later. ```bash npm install -g "@codacy/codacy-cloud-cli"