Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/instructions/action-yaml.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Programmatic access: `#actionSchema()`, `#actionSpelFunctions()` (available insi

## SpEL Expression Scope

- **`cli.options::default`** — Only `ActionSpelFunctions` + `#env()`; NO action context, NO product-specific functions
- **`cli.options::default`** — Only `ActionSpelFunctions` + `#env()` + `#<ci>.env` (e.g. `#ado.env`, `#github.env`); NO action context, NO product-specific functions
- **`steps` section** — Full access: all SpEL functions, action variables, product-specific (`fod.*`, `ssc.*`), CI-specific (`github.*`, `gitlab.*`, `ado.*`)

## YAML/SpEL Pitfalls
Expand Down
2 changes: 1 addition & 1 deletion .github/skills/fcli-action-yaml-reference/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Detailed reference material for developing fcli action YAML files. The always-on

Default values for CLI options — evaluated **before** action steps run.

- Only `ActionSpelFunctions` + `#env()` available
- Only `ActionSpelFunctions` + `#env()` + `#<ci>.env` (e.g. `#ado.env`, `#github.env`) available
- Evaluated via `ActionRunnerConfig.getSpelEvaluator()`
- **NOT available:** `ActionRunnerContextSpelFunctions` (`action.*`), product-specific functions (`fod.*`, `ssc.*`), action variables, execution context

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ usage:
description: |
This action collects data about the current environment in which fcli is being run,
like the current CI/CD platform (GitHub, GitLab, Azure DevOps, ...), Git data from
current source code directory, ... Collected data is stored in global.ci.* action
current source code directory, ... Collected data is stored in global.ci.* action
variables for use by other actions, and printed to the output for user reference.
This includes both environment-specific data, and any data derived from that data,
like default FoD release name and SSC application version name.

config:
output: immediate
mcp: exclude

steps:
# Only run if not run before; global.isCiInitialized is set at the end of this action.
# Callers may also check this variable to avoid re-running this action.
Expand All @@ -26,9 +26,9 @@ steps:
global.ci.fcliVersion: ${fcliBuildProps.fcliVersion} # Fcli version
global.ci.fcliBuildInfo: ${fcliBuildProps.fcliBuildInfo} # Fcli build information
global.ci.name: # Name of current CI system
global.ci.id: # Id of current CI system, used to look up <id>-* actions
global.ci.id: # Id of current CI system, used to look up <id>-* actions
global.ci.qualifiedRepoName: # Fully qualified repository name
global.ci.sourceBranch: # The current branch being processed/scanned
global.ci.sourceBranch: # The current branch being processed/scanned
global.ci.commitHeadSHA: # Head commit SHA (actual commit on branch)
global.ci.commitMergeSHA: # Merge commit SHA (for PRs on GitHub, same as head otherwise)
global.ci.workspaceDir: "." # Workspace/repository root directory (default to current dir)
Expand All @@ -38,6 +38,7 @@ steps:
global.ci.prId: # Pull/merge request numeric identifier (null if not active)
global.ci.prTarget: # Pull/merge request target branch (null if not active)
global.ci.prTerminology: "Pull Request" # Pull/merge request terminology for this CI system (default)
global.ci.prKeyword: # Keyword for PR actions: 'pr' for GitHub/ADO, 'mr' for GitLab
# The following are set by default at the end, but may be overridden by individual CI configurations
global.fod.prCommentAction: # FoD PR comment action
global.ssc.prCommentAction: # SSC PR comment action
Expand All @@ -52,7 +53,7 @@ steps:
ci.detected: ${#_ci.detect()}
ci.type: ${ci.detected.type}
ci.env: ${ci.detected.env}

# For recognized CI systems (not unknown), extract properties from detected environment
# Using conditional navigation operator ?. to safely access properties even if ci.env is empty
- if: ${ci.type!='unknown'}
Expand All @@ -69,20 +70,21 @@ steps:
global.ci.prId: ${ci.env?.pullRequest?.id}
global.ci.prTarget: ${ci.env?.pullRequest?.target}
global.ci.prTerminology: ${ci.env?.prTerminology?:global.ci.prTerminology}

global.ci.prKeyword: ${ci.env?.prKeyword?:global.ci.prKeyword}

# GitHub-specific properties
- if: ${ci.type=='github'}
var.set:
global.ci.jobSummaryFile: ${#ifBlank(global.ci.jobSummaryFile,ci.env?.jobSummaryFile)}

# Jenkins
- if: ${#isNotBlank(#env('JENKINS_HOME'))||#isNotBlank(#env('JENKINS_URL'))}
var.set:
global.ci.name: Jenkins
global.ci.id: jenkins
global.ci.workspaceDir: ${#env('WORKSPACE')}
global.ci.sourceDir: ${#env('WORKSPACE')}

# Override sourceDir with SOURCE_DIR if specified (custom user variable)
# NOTE: workspaceDir is NOT overridden by SOURCE_DIR, as it should always be the workspace root
- if: ${#isNotBlank(#env('SOURCE_DIR'))}
Expand All @@ -93,8 +95,8 @@ steps:
global.ci.workspaceDir: ${#ifBlank(global.ci.workspaceDir,'.')}
global.ci.sourceDir: ${#ifBlank(global.ci.sourceDir,'.')}
- var.set:
global.ci.localRepo: ${#localRepo(global.ci.sourceDir)}
global.ci.localRepo: ${#git.localRepo(global.ci.sourceDir)}

# Generic local repository fallback (run if previous CI-specific steps didn't set these)
- if: ${#isBlank(global.ci.id) && global.ci.localRepo!=null}
var.set:
Expand All @@ -104,31 +106,36 @@ steps:
global.ci.sourceBranch: ${global.ci.localRepo.branch?.short}
global.ci.commitHeadSHA: ${global.ci.localRepo.commit?.headId?.full}
global.ci.commitMergeSHA: ${global.ci.localRepo.commit?.mergeId?.full}

# Additional generic variables based on the output of the CI-specific sections above
- var.set:
global.ci.defaultFortifyRepo: ${#joinOrNull(':', global.ci.qualifiedRepoName, global.ci.sourceBranch)}
# Set default reporting actions based on ci identifier. Note that FoD/SSC CI actions should check existence of these actions
# Set default reporting actions based on ci identifier. Note that FoD/SSC CI actions should check existence of these actions
# TODO Only use default values if not explicitly defined in CI-specific sections above.
global.ci.fod_prCommentAction: ${#actionOrNull('fod',#joinOrNull('-', global.ci.id, 'pr-comment'))}
global.ci.ssc_prCommentAction: ${#actionOrNull('ssc',#joinOrNull('-', global.ci.id, 'pr-comment'))}
global.ci.fod_prCommentAction: ${#actionOrNull('fod',#joinOrNull('-', global.ci.id, global.ci.prKeyword, 'comment'))}
global.ci.ssc_prCommentAction: ${#actionOrNull('ssc',#joinOrNull('-', global.ci.id, global.ci.prKeyword, 'comment'))}
global.ci.fod_sastExportAction: ${#actionOrNull('fod',#joinOrNull('-', global.ci.id, 'sast-report'))}
global.ci.ssc_sastExportAction: ${#actionOrNull('ssc',#joinOrNull('-', global.ci.id, 'sast-report'))}
global.ci.fod_dastExportAction: ${#actionOrNull('fod',#joinOrNull('-', global.ci.id, 'dast-report'))}
global.ci.ssc_dastExportAction: ${#actionOrNull('ssc',#joinOrNull('-', global.ci.id, 'dast-report'))}
global.ci.fod_scaExportAction: ${#actionOrNull('fod',#joinOrNull('-', global.ci.id, 'debricked-report'))} # TODO 'debricked' or more generic 'sca' or 'composition (analysis)'
global.ci.ssc_scaExportAction: ${#actionOrNull('ssc',#joinOrNull('-', global.ci.id, 'debricked-report'))} # TODO 'debricked' or more generic 'sca' or 'composition (analysis)'
# Aviator remediations action: use a CI-specific <id>-remediations-<pr|mr> action if it exists
# (e.g. github-remediations-pr for GitHub PR creation), otherwise fall back to the generic
# push-remediations action that only pushes changes to a new branch.
global.ci.fod_aviatorRemediationsAction: ${#actionOrNull('fod',#joinOrNull('-', global.ci.id, 'remediations', global.ci.prKeyword))?:'push-remediations'}
global.ci.ssc_aviatorRemediationsAction: ${#actionOrNull('ssc',#joinOrNull('-', global.ci.id, 'remediations', global.ci.prKeyword))?:'push-remediations'}
# Set PR-related skip reason if not active
- if: "${global.ci.prActive!=true}"
var.set:
global.ci.prNotActiveSkipReason: "Not a ${global.ci.prTerminology}"
- log.info: "${global.ci.name!=null ? 'Detected '+global.ci.name : 'No CI system detected'}"
- log.info: {msg: "${global.ci.name!=null ? 'Detected '+global.ci.name : 'No CI system detected'}"}
- records.for-each:
from: ${#properties(global.ci)}
record.var-name: p
do:
- if: ${#isDebugEnabled() || p.value!=null}
log.info: "${' '+p.key+': '+p.value}"
log.info: {msg: "${' '+p.key+': '+p.value}"}

# Mark as initialized to prevent re-running this action
- var.set:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
fcli.ai-assist.usage.header = (PREVIEW) Manage AI assistant integrations
fcli.ai-assist.usage.header = Manage AI assistant integrations
fcli.ai-assist.usage.description = Manage AI-related functionality like MCP servers and skills.

# fcli ai-assist extensions
fcli.ai-assist.extensions.definitions.note = NOTE: Available extension versions, download URLs, and assistant detection logic are managed through fcli tool definitions (`ai-assistant-extensions*` at https://github.com/fortify/tool-definitions/tree/main/v1). Run `fcli tool definitions update` before running this command.
fcli.ai-assist.extensions.usage.header = (PREVIEW) Manage Fortify extensions for AI coding assistants
fcli.ai-assist.extensions.usage.header = Manage Fortify extensions for AI coding assistants
fcli.ai-assist.extensions.usage.description = Set up, uninstall, or check status of Fortify extensions (skills, agents, plugins) for AI coding assistants like Claude Code, GitHub Copilot, OpenAI Codex, and Gemini CLI.%n\
%n${fcli.ai-assist.extensions.definitions.note}
fcli.ai-assist.extensions.setup.usage.header = Set up Fortify extensions for coding assistants
Expand Down Expand Up @@ -60,10 +60,10 @@ fcli.ai-assist.extensions.detect = Run detection checks (glob patterns, command

# fcli ai-assist mcp
fcli.ai-assist.mcp.skills.note = NOTE: For better user experience and potentially lower token usage, consider Fortify skills from https://github.com/fortify/skills, which can be installed through your AI assistant marketplace (if available) or by utilizing the `fcli ai-assist extensions' commands.
fcli.ai-assist.mcp.usage.header = (PREVIEW) Manage fcli MCP server commands for AI assistants
fcli.ai-assist.mcp.usage.header = Manage fcli MCP server commands for AI assistants
fcli.ai-assist.mcp.usage.description = Start fcli MCP servers for AI assistants.%n\
%n${fcli.ai-assist.mcp.skills.note}
fcli.ai-assist.mcp.start-stdio.usage.header = (PREVIEW) Start fcli stdio MCP server.
fcli.ai-assist.mcp.start-stdio.usage.header = Start fcli stdio MCP server.
fcli.ai-assist.mcp.start-stdio.usage.description = Start the fcli MCP server over stdio. This command exposes fcli module commands and/or \
imported action functions as MCP tools to AI clients.%n\
%n${fcli.ai-assist.mcp.skills.note}%n\
Expand All @@ -82,7 +82,7 @@ fcli.ai-assist.mcp.start-stdio.job-safe-return = Maximum time to wait synchronou
fcli.ai-assist.mcp.start-stdio.progress-interval = Interval between internal progress counter updates for long-running jobs. Specify duration (e.g. 500ms, 1s, 2s).
fcli.ai-assist.mcp.start-stdio.async-bg-threads = Number of background threads for running async streaming jobs. Default: 2.

fcli.ai-assist.mcp.start-http.usage.header = (PREVIEW) Start fcli HTTP MCP server.
fcli.ai-assist.mcp.start-http.usage.header = Start fcli HTTP MCP server.
fcli.ai-assist.mcp.start-http.usage.description = Start an HTTP MCP server exposing only exported functions from imported action YAML files defined in a config file. Generate a sample config file with 'fcli ai-assist mcp create-http-config --type <ssc|fod>' and customize the generated YAML for your environment. The server listens for MCP POST requests on the /mcp endpoint. Each request must include the product-specific auth header as semicolon-separated key=value pairs; escape literal '\\', ';', or '=' characters as '\\\\', '\\;', or '\\='.\
%n%n${fcli.ai-assist.mcp.skills.note}\
%n%nNOTE: The HTTP MCP server exposes a larger attack surface than local stdio MCP server; use HTTP MCP server only when needed and prefer HTTPS with properly configured certificates.\
Expand Down
Loading
Loading