From a16a87a56efc536ea6160c84d5e8ce6fa398227f Mon Sep 17 00:00:00 2001 From: kadraman Date: Thu, 11 Jun 2026 10:21:43 +0100 Subject: [PATCH 1/2] Implementation of `gitlab-pr-comment` action with similar behaviour to `github-pr-comment` for FoD. --- .../fod/actions/zip/gitlab-pr-comment.yaml | 146 ++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/gitlab-pr-comment.yaml diff --git a/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/gitlab-pr-comment.yaml b/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/gitlab-pr-comment.yaml new file mode 100644 index 00000000000..7c62c20ad61 --- /dev/null +++ b/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/gitlab-pr-comment.yaml @@ -0,0 +1,146 @@ +# yaml-language-server: $schema=https://fortify.github.io/fcli/schemas/action/fcli-action-schema-2.8.0.json + +# For now, this template uses latest release state to generate MR comments. +# It is named "gitlab-pr-comment" (rather than gitlab-mr-comment) for consistency +# and so it can be picked up automatically by default for GitLab CI environments. + +author: Fortify +usage: + header: (PREVIEW) Add GitLab Merge Request comment. + description: | + This action adds review comments to a GitLab Merge Request. Currently + this is marked as PREVIEW as we build out this functionality; later + versions may have different behavior and/or require different action + cli. + + For best results, this fcli action should only be run on GitLab + merge_request_event. Upon MR creation, a new FoD release should + be created, copying state from the FoD release that represents the + branch into which the PR will be merged, and a new scan should be + run on the current MR branch before invoking this fcli action. + + This will ensure that scan results for the current MR will be + compared against the latest scan results for the target branch + upon MR creation. Optionally, new scans can be run upon MR changes, + creating new MR comments that show the issue delta compared to the + previous scan for this MR. + + You will need to provide a GitLab token or set the environment + variable "GITLAB_API_TOKEN" with permissions to post comments on + the MR, and the GitLab API URL if not using gitlab.com. The + project id and MR IID must also be provided, but can be automatically + populated from CI environment variables if running in GitLab CI. + +config: + rest.target.default: fod + +cli.options: + release: + names: --release, --rel + description: "Required release id or :[:]. Default value FOD_RELEASE environment variable." + required: true + default: ${#env('FOD_RELEASE')} + scan-type: + names: --scan-type, -t + description: "Scan type for which to list vulnerabilities. Default value Static." + required: true + default: Static + gitlab-api-url: + names: --gitlab-api-url + description: "Required GitLab API URL. Default value CI_API_V4_URL environment variable." + required: true + default: ${#env('CI_API_V4_URL')} + gitlab-token: + names: --gitlab-token + description: "Required GitLab token. Defaults to GITLAB_API_TOKEN. CI_JOB_TOKEN is not supported for posting MR comments." + required: true + default: ${#env('GITLAB_API_TOKEN')} + mask: + sensitivity: high + project-id: + names: --project-id + description: "Required GitLab project id. Default value CI_PROJECT_ID environment variable." + required: true + default: ${#env('CI_PROJECT_ID')} + mr-iid: + names: --mr-iid + description: "Required Merge Request IID. Default value CI_MERGE_REQUEST_IID environment variable." + required: true + default: ${#env('CI_MERGE_REQUEST_IID')} + dryrun: + names: --dryrun + description: "Set to true to output request body without posting comment." + type: boolean + required: false + default: false + +steps: + - rest.target: + gitlab: + baseUrl: ${cli['gitlab-api-url']} + headers: + PRIVATE-TOKEN: ${cli['gitlab-token']} + - var.set: + rel: ${#fod.release(cli.release)} + - log.progress: Processing issue data + - rest.call: + issues: + uri: /api/v3/releases/${rel.releaseId}/vulnerabilities?limit=50 + query: + includeFixed: true + filters: scantype:${cli['scan-type']} + log.progress: + page.post-process: Processed ${totalIssueCount?:0} of ${issues_raw.totalCount} issues + records.for-each: + record.var-name: issue + if: ${issue.status!='Existing'} + do: + - var.set: + removedIssues..: {fmt: mdIssueListItem, if: "${issue.status=='Fix Validated'}"} + newIssues..: {fmt: mdIssueListItem, if: "${(issue.status=='New' || issue.status=='Reopen')}"} + + - var.set: + reviewBody: {fmt: reviewBody} + noteRequestBody: {fmt: noteRequestBody} + hasIssueStatusChanges: ${newIssues!=null || removedIssues!=null} + + - if: ${cli.dryrun && hasIssueStatusChanges} + log.info: ${noteRequestBody} + + - if: ${cli.dryrun && !hasIssueStatusChanges} + log.info: No issue status changes detected; skipping MR note. + + - if: ${!cli.dryrun && hasIssueStatusChanges} + rest.call: + postMRNote: + method: POST + uri: /projects/${cli['project-id']}/merge_requests/${cli['mr-iid']}/notes + target: gitlab + body: ${noteRequestBody} + + - if: ${!cli.dryrun && !hasIssueStatusChanges} + log.info: No issue status changes detected; not posting MR note. + +formatters: + noteRequestBody: + body: ${reviewBody} + + reviewBody: | + ## Fortify vulnerability summary + + Any issues listed below are based on comparing the latest scan results against the previous + scan results in FoD release [${rel.applicationName}${#isNotBlank(rel.microserviceName)?' - '+rel.microserviceName:''} - ${rel.releaseName}](${#fod.releaseBrowserUrl(rel)}). + + ### New Issues + + ${newIssues==null + ? "* No new or re-introduced issues were detected" + : ("* "+#join('\n* ',newIssues))} + + ### Removed Issues + + ${removedIssues==null + ? "* No removed issues were detected" + : ("* "+#join('\n* ',removedIssues))} + + mdIssueListItem: "${issue.status} (${issue.scantype}) - ${issue.category}: \n[${issue.primaryLocationFull}${issue.lineNumber==null?'':':'+issue.lineNumber}](${#fod.issueBrowserUrl(issue)})" From 604b2da769289b87952b9fdf7281a65e7b71a251 Mon Sep 17 00:00:00 2001 From: kadraman Date: Thu, 11 Jun 2026 10:50:15 +0100 Subject: [PATCH 2/2] Updated `fcli fod action run gitlab-pr-comment` to use GITLAB_TOKEN environment variable. --- .../cli/fod/actions/zip/gitlab-pr-comment.yaml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/gitlab-pr-comment.yaml b/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/gitlab-pr-comment.yaml index 7c62c20ad61..ef72848ae5c 100644 --- a/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/gitlab-pr-comment.yaml +++ b/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/gitlab-pr-comment.yaml @@ -25,10 +25,11 @@ usage: creating new MR comments that show the issue delta compared to the previous scan for this MR. - You will need to provide a GitLab token or set the environment - variable "GITLAB_API_TOKEN" with permissions to post comments on - the MR, and the GitLab API URL if not using gitlab.com. The - project id and MR IID must also be provided, but can be automatically + You will need to provide a GitLab token or set one of the environment + variables "GITLAB_TOKEN" (recommended) or "GITLAB_API_TOKEN" with + permissions to post comments on the MR, and the GitLab API v4 base URL + (e.g., https://gitlab.com/api/v4) if not using the default gitlab.com. + The project id and MR IID must also be provided, but can be automatically populated from CI environment variables if running in GitLab CI. config: @@ -47,14 +48,14 @@ cli.options: default: Static gitlab-api-url: names: --gitlab-api-url - description: "Required GitLab API URL. Default value CI_API_V4_URL environment variable." + description: "Required GitLab API v4 base URL (e.g., https://gitlab.com/api/v4 or https://gitlab.example.com/api/v4). Default value CI_API_V4_URL environment variable." required: true default: ${#env('CI_API_V4_URL')} gitlab-token: names: --gitlab-token - description: "Required GitLab token. Defaults to GITLAB_API_TOKEN. CI_JOB_TOKEN is not supported for posting MR comments." + description: "Required GitLab token. Defaults to GITLAB_TOKEN, falls back to GITLAB_API_TOKEN. CI_JOB_TOKEN is supported if configured with appropriate permissions." required: true - default: ${#env('GITLAB_API_TOKEN')} + default: "${#ifBlank(#env('GITLAB_TOKEN'), #env('GITLAB_API_TOKEN'))}" mask: sensitivity: high project-id: