Documentation
¶
Index ¶
- Constants
- Variables
- func BranchExists(projectID int, branch string, token string, APIURL string, ...) (bool, error)
- func BranchMatchesPattern(pattern, branchName string) bool
- func CIAnalyzedRef() string
- func CIConfigPathIsExternal(path string) bool
- func CheckoutIsAtRef(branch string) bool
- func CollectOverriddenJobs(o *GitlabPipelineOriginDataFull, data *GitlabPipelineOriginData) []ir.OverriddenJob
- func ConvertCICDVariableToMap(variables []CICDVariable) map[string]string
- func CreateMergeRequestNote(projectID int, mrIID int, body string, token string, instanceURL string, ...) (*gitlab.Note, error)
- func CreateProjectBadge(projectID int, name, imageURL, linkURL, token, instanceURL string, ...) (*gitlab.ProjectBadge, error)
- func DeclaredVariableNames(run *platform.RunContext) []string
- func DetectMergeRequestIID() int
- func FetchGitlabFile(projectPath string, filePath string, ref string, token string, APIURL string, ...) ([]byte, error, error)
- func FetchGitlabInclude(include MergedCIConfResponseInclude, projectPath, token, APIURL, sha string, ...) ([]string, error)
- func FetchGitlabProject(id int, token string, APIURL string, conf *configuration.Configuration) (*gitlab.Project, error, error)
- func FetchLatestCommitSha(token, instanceURL, projectPath, branch string, ...) (string, error)
- func FetchProjectMRApprovalRules(projectID int, token string, APIURL string, conf *configuration.Configuration) ([]*gitlab.ProjectApprovalRule, int, error)
- func FetchProjectMRApprovalSettings(projectID int, token string, APIURL string, conf *configuration.Configuration) (*gitlab.ProjectApprovals, int, error)
- func GetExtends(extendsInterface interface{}) ([]string, error)
- func GetFullGitlabCI(project *ProjectInfo, ref, token, url string, ...) (*GitlabCIConf, *GitlabCIConf, *MergedCIConfResponse, string, string, error)
- func GetGraphQLClient(url string, conf *configuration.Configuration) *graphql.Client
- func GetImageName(imageInterface interface{}) (string, error)
- func GetMapKeys(m map[string]string) []string
- func GetNewGitlabClient(token string, instanceUrl string, conf *configuration.Configuration) (*gitlab.Client, error)
- func GetVariableValue(valueInterface interface{}) (string, error)
- func IsOnDefaultBranchCI() bool
- func IsRunningInCI() bool
- func IsUpToDate(version, latestVersion string, latestRefs []string) bool
- func JobEnvironmentVariables(declared []string) map[string]string
- func ListMergeRequestNotes(projectID int, mrIID int, token string, instanceURL string, ...) ([]*gitlab.Note, error)
- func ListProjectBadges(projectID int, token string, instanceURL string, ...) ([]*gitlab.ProjectBadge, error)
- func ParseDefaultImage(conf *GitlabCIConf) (string, error)
- func ParseGitlabComponentPath(path string, instanceURL string) (string, string, string)
- func ParseGlobalVariables(conf *GitlabCIConf) (map[string]string, error)
- func ParseJobVariables(job *GitlabJob) (map[string]string, error)
- func RefResolvesAsTagAndBranch(projectPath string, ref string, token string, APIURL string, ...) (tagExists bool, branchExists bool, err error)
- func ReplaceVariable(input string, ...) string
- func ResolveLocalIncludes(content []byte, repoRoot string) ([]byte, error)
- func ResolveWithinRepo(repoRoot, relPath string) (string, error)
- func SearchTags(projectPath string, token string, APIURL string, ...) ([]string, error, error)
- func SplitComponentPath(cleanPath string) (project string, component string)
- func ToNormalizedPipeline(projectPath string, defaultBranch string, ciConfigPath string, ...) *ir.NormalizedPipeline
- func UpdateMergeRequestNote(projectID int, mrIID int, noteID int, body string, token string, ...) (*gitlab.Note, error)
- func UpdateProjectBadge(projectID int, badgeID int, name, imageURL, linkURL, token, instanceURL string, ...) (*gitlab.ProjectBadge, error)
- func WrapTransportWithRetry(transport http.RoundTripper, conf *configuration.Configuration) http.RoundTripper
- type Artifacts
- type Branch
- type BranchProtection
- type BranchProtectionAccessLevel
- type CICDVariable
- func GetGitlabInstanceVariables(token string, instanceUrl string, conf *configuration.Configuration) ([]CICDVariable, error)
- func GetGitlabProjectInheritedVariables(fullPath string, token string, instanceUrl string, ...) ([]CICDVariable, error)
- func GetGitlabProjectVariables(fullPath string, token string, instanceUrl string, ...) ([]CICDVariable, error)
- type CICDVariableConf
- type CICDVariableSource
- type CICatalogResource
- type CICatalogResourceVersion
- type CIComponent
- type CIConfDefault
- type CIConfVariable
- type Cache
- type Environment
- type Except
- type GitlabCIConf
- type GitlabJob
- type GitlabPipelineImageData
- type GitlabPipelineImageDataCollection
- type GitlabPipelineImageInfo
- type GitlabPipelineImageMetrics
- type GitlabPipelineJobData
- type GitlabPipelineJobGitlabComponent
- type GitlabPipelineJobPlumberOrigin
- type GitlabPipelineOriginData
- type GitlabPipelineOriginDataCollection
- type GitlabPipelineOriginDataFull
- type GitlabPipelineOriginDataGeneric
- type GitlabPipelineOriginDataProjectSpecific
- type GitlabPipelineOriginMetrics
- type GitlabProtectionAnalysisData
- type GitlabProtectionData
- type GitlabProtectionDataBranch
- type GitlabProtectionDataCollection
- type GitlabProtectionMetrics
- type GitlabVariablesAnalysisData
- type Group
- type GroupMetadataNode
- type GroupProjectsResponse
- type Image
- type Include
- type IncludeJobs
- type IncludeJobsRequest
- type IncludeList
- type IncludeOrigin
- type IncludeOriginWithoutRef
- type InstanceGroupsResponse
- type InstanceProjectsResponse
- type MergedCIConfResponse
- type MergedCIConfResponseInclude
- type Only
- type PageInfo
- type Project
- type ProjectBranchesResponse
- type ProjectInfo
- type ProjectLanguage
- type ProjectMetadataNode
- type Resource
- type Resources
- type RetryConfig
- type Rule
- type SecurityPolicyData
- type SecurityPolicyProject
- type SecurityPolicyProjectLink
- type Service
- type StringOrSlice
- type Workflow
Constants ¶
const ( // PlumberBadgeName is the name used for Plumber project badges PlumberBadgeName = "Plumber" // UnableToGetGitlabClient is the error message for when a Gitlab client cannot be created UnableToGetGitlabClient = "Unable to get a Gitlab client" )
const ( BehaviorWhenCommitIsAddedKeepApprovalsId = iota + 1 BehaviorWhenCommitIsAddedRemoveCodeOwnerApprovalsId BehaviorWhenCommitIsAddedRemoveApprovalsId )
Behavior when commit is added constants
const ( BehaviorWhenCommitIsAddedKeepApprovalsText = "Keep approvals" BehaviorWhenCommitIsAddedRemoveCodeOwnerText = "Remove approvals by Code Owners if their files changed" BehaviorWhenCommitIsAddedRemoveApprovalsText = "Remove all approvals" )
Behavior when commit is added text values
const ( SquashOptionNever = "never" // Never squash SquashOptionAlways = "always" // Always squash SquashOptionDefaultOn = "default_on" // Squash by default (can be turned off) SquashOptionDefaultOff = "default_off" // Don't squash by default (can be turned on) )
GitLab squash option constants
const ( AccessLevelNo = 0 AccessLevelMinimal = 5 AccessLevelGuest = 10 AccessLevelPlanner = 15 AccessLevelReporter = 20 AccessLevelDeveloper = 30 AccessLevelMaintainer = 40 AccessLevelOwner = 50 AccessLevelAdmin = 60 )
Access level constants for GitLab
const ( NoText = "No access" MinimalText = "Minimal access" GuestText = "Guest" PlannerText = "Planner" ReporterText = "Reporter" DeveloperText = "Developer" MaintainerText = "Maintainer" OwnerText = "Owner" AdminText = "Admin" )
Access level text descriptions
const ( IncludeFile = "file" IncludeRemote = "remote" )
const DataCollectionTypeGitlabPipelineImageVersion = "0.2.0"
const DataCollectionTypeGitlabPipelineOriginVersion = "0.2.0"
const (
DataCollectionTypeGitlabProtectionVersion = "0.2.0"
)
Variables ¶
var ErrProjectVariablesUnreadable = errors.New("project CI/CD variables not readable (insufficient token permissions)")
ErrProjectVariablesUnreadable signals that GetGitlabProjectVariables got a well-formed HTTP 200 whose GraphQL `project`/`ciVariables` resolved to null — the token authenticated but lacks the role to read CI/CD variables (Maintainer+ / admin_cicd_variables). Callers that must never turn "unreadable" into a silent empty pass (the settings-variable controls, #418) treat any error as not-evaluable. Callers that only want the values opportunistically (image-ref resolution) check errors.Is for this sentinel and proceed with no project variables instead of failing the whole run.
Functions ¶
func BranchExists ¶ added in v0.3.53
func BranchExists(projectID int, branch string, token string, APIURL string, conf *configuration.Configuration) (bool, error)
BranchExists reports whether the given branch (or tag/ref) exists in the project. A 404 from the API means it does not exist and is returned as (false, nil); any other failure (auth, network) is a real error. Used to tell a non-existent --branch apart from a branch that simply has no .gitlab-ci.yml, so the former fails loudly instead of rendering a confusing limited report (#222).
func BranchMatchesPattern ¶
BranchMatchesPattern checks if a branch name matches a pattern using wildcard matching Supports * wildcard for pattern matching (e.g., "*production*", "release/*")
func CIAnalyzedRef ¶ added in v0.4.50
func CIAnalyzedRef() string
CIAnalyzedRef returns the ref this job checked out, or "" outside CI.
A run that names no branch analyses whatever it is standing in, which in a CI job is $CI_COMMIT_REF_NAME - not the project's default branch. Without this the two come apart on every feature-branch pipeline: the run reads the branch's own CI file off disk and then labels the report with the default branch, so every source link points at a ref the finding is not on. The GitLab component always passes `branch:`, which hides it; the CLI should not need the template to be right.
func CIConfigPathIsExternal ¶ added in v0.4.50
CIConfigPathIsExternal reports whether a ci_config_path points somewhere other than this repository.
GitLab accepts three forms: a repo-relative path, `file.yml@group/project` (optionally `:ref`), and a bare URL. Only the first can be read from a checkout or from this project's file API, so the other two are a fetch that is certain to 404 - and $CI_CONFIG_PATH exports whichever form the project configured, verbatim.
internal/cidigest already refuses the same shapes when computing a digest (ErrExternalRootConfig); this is the collection-side half of the same rule.
func CheckoutIsAtRef ¶ added in v0.4.50
CheckoutIsAtRef reports whether the working tree this job was given is the ref being analyzed.
It exists so the analyzed project's own CI file can be read from disk instead of fetched over the API. That substitution is only sound when the tree holds the ref in question: reading one branch's file while reporting on another's is a wrong answer no downstream check would catch, because the file parses perfectly either way.
An empty branch means "the run did not name one", which is the analyzed ref by definition. Otherwise it has to match the ref the job checked out.
func CollectOverriddenJobs ¶ added in v0.3.65
func CollectOverriddenJobs(o *GitlabPipelineOriginDataFull, data *GitlabPipelineOriginData) []ir.OverriddenJob
CollectOverriddenJobs returns the jobs inherited from origin that were locally redefined with forbidden CI/CD keys. The IR uses it to expose override metadata to Rego policies; the PBOM generator reuses it so both paths share the same rule for what counts as an override.
func ConvertCICDVariableToMap ¶
func ConvertCICDVariableToMap(variables []CICDVariable) map[string]string
func CreateMergeRequestNote ¶ added in v0.1.42
func CreateMergeRequestNote(projectID int, mrIID int, body string, token string, instanceURL string, conf *configuration.Configuration) (*gitlab.Note, error)
CreateMergeRequestNote creates a new note (comment) on a merge request
func CreateProjectBadge ¶ added in v0.1.42
func CreateProjectBadge(projectID int, name, imageURL, linkURL, token, instanceURL string, conf *configuration.Configuration) (*gitlab.ProjectBadge, error)
CreateProjectBadge creates a new badge on a project
func DeclaredVariableNames ¶ added in v0.4.50
func DeclaredVariableNames(run *platform.RunContext) []string
DeclaredVariableNames returns the names of every CI/CD variable the platform collected for this project that can legitimately appear inside an image reference.
Scope is deliberately NOT filtered here, unlike VariablesFromSnapshot. The settings-variable controls judge the project's own variables and must not be handed a group's; expanding a placeholder is the opposite case, because a job resolves `$REGISTRY` against everything it inherits and does not care which scope defined it.
What IS filtered is every variable whose value the analysing job cannot stand in for. The values come from THIS job's environment, and the references being expanded belong to every job in the pipeline, so a variable is only usable here when its value is the same for all of them and is not a secret:
- FILE type. GitLab exports a file variable as the PATH of a temporary file, not its contents, so substituting would render `$CERT/app` as `/builds/project.tmp/CERT/app` - a reference that looks resolved and is not one.
- An environment scope other than `*`. Scope is resolved per job from that job's own `environment:` keyword, so this job's answer is not the other jobs' answer. Substituting it would put a plausible but wrong registry into another job's reference, which is worse than leaving the placeholder: a wrong answer nothing can detect, instead of an abstention.
- MASKED or HIDDEN. The value is a declared secret. Expanding it puts it into a finding message, the JSON report and the pushed result, which is exactly what the #370 sensitivity tiers forbid. A reference built out of a secret cannot be judged without disclosing it, so abstaining is the only honest option.
Everything excluded here simply stays a placeholder, gets marked unresolved, and makes the image rules abstain on that one job.
Names only: the values come from the job's own environment (JobEnvironmentVariables), and the platform serves no values at all.
func DetectMergeRequestIID ¶ added in v0.1.42
func DetectMergeRequestIID() int
DetectMergeRequestIID checks if we are running inside a GitLab CI merge request pipeline and returns the merge request IID. Returns 0 if not in a CI merge request context.
GitLab CI sets CI_MERGE_REQUEST_IID only for merge request pipelines (pipelines triggered by `rules: - if: $CI_MERGE_REQUEST_IID` or `only: merge_requests`).
func FetchGitlabFile ¶
func FetchGitlabFile(projectPath string, filePath string, ref string, token string, APIURL string, conf *configuration.Configuration) ([]byte, error, error)
FetchGitlabFile retrieves a file from a GitLab project using its path
func FetchGitlabInclude ¶
func FetchGitlabInclude(include MergedCIConfResponseInclude, projectPath, token, APIURL, sha string, conf *configuration.Configuration, inputs map[string]interface{}, stages []string) ([]string, error)
FetchGitlabInclude retrieves all jobs from a CI conf include
func FetchGitlabProject ¶
func FetchGitlabProject(id int, token string, APIURL string, conf *configuration.Configuration) (*gitlab.Project, error, error)
FetchGitlabProject retrieves a project from GitLab using its ID
func FetchLatestCommitSha ¶ added in v0.1.33
func FetchLatestCommitSha(token, instanceURL, projectPath, branch string, conf *configuration.Configuration) (string, error)
FetchLatestCommitSha gets the latest commit SHA for a given branch. Exported wrapper around fetchLatestCommitSha for use outside the gitlab package.
func FetchProjectMRApprovalRules ¶
func FetchProjectMRApprovalRules(projectID int, token string, APIURL string, conf *configuration.Configuration) ([]*gitlab.ProjectApprovalRule, int, error)
FetchProjectMRApprovalRules retrieves MR approval rules for a project. The second return is the HTTP status of a failed request (0 when there was no response), so the caller can classify a 403/404 (feature unavailable / token scope → not-evaluable) apart from a hard failure on the typed status rather than substring-matching the error string.
func FetchProjectMRApprovalSettings ¶
func FetchProjectMRApprovalSettings(projectID int, token string, APIURL string, conf *configuration.Configuration) (*gitlab.ProjectApprovals, int, error)
FetchProjectMRApprovalSettings retrieves MR approval settings for a project. The second return is the HTTP status of a failed request (0 when there was no response), so the caller classifies a 403/404 apart from a hard failure on the typed status.
func GetExtends ¶
GetExtends gets the extends entry and returns a slice of string with all extends
func GetFullGitlabCI ¶
func GetFullGitlabCI(project *ProjectInfo, ref, token, url string, conf *configuration.Configuration) (*GitlabCIConf, *GitlabCIConf, *MergedCIConfResponse, string, string, error)
GetFullGitlabCI retrieves the full GitLab CI configuration for a project
func GetGraphQLClient ¶
func GetGraphQLClient(url string, conf *configuration.Configuration) *graphql.Client
GetGraphQLClient creates a GraphQL client with retry logic
func GetImageName ¶
GetImageName gets the image name from an interface parsed from gitlab ci file
func GetMapKeys ¶
GetMapKeys returns the keys of a string map as a slice (for safe logging without values)
func GetNewGitlabClient ¶
func GetNewGitlabClient(token string, instanceUrl string, conf *configuration.Configuration) (*gitlab.Client, error)
GetNewGitlabClient returns a new GitLab client for API requests
func GetVariableValue ¶
GetVariableValue gets the variable value from an interface parsed from gitlab ci file
func IsOnDefaultBranchCI ¶ added in v0.1.42
func IsOnDefaultBranchCI() bool
IsOnDefaultBranchCI checks if the current CI pipeline is running on the project's default branch by comparing CI_COMMIT_BRANCH to CI_DEFAULT_BRANCH. Only call this when IsRunningInCI() returns true.
func IsRunningInCI ¶
func IsRunningInCI() bool
IsRunningInCI checks if the code is running inside a GitLab CI environment by checking if the CI environment variable is set to "true"
func IsUpToDate ¶
Return if a template is up to date
func JobEnvironmentVariables ¶ added in v0.4.50
JobEnvironmentVariables returns the values this job's environment holds for the CI/CD variables it is allowed to expand, keyed by name.
Two sources, and the split is deliberate:
- Every variable under a GitLab-reserved prefix. These are predefined and their names are not user-chosen, so reading them needs no permission from anyone. `$CI_REGISTRY_IMAGE` is by far the most common placeholder in a real image reference.
- Every name in declared, which is the variable metadata the platform serves. Restricting the user-defined half to names the platform vouched for is what keeps this from being "read the process environment": an unrelated `$HOME` or `$PATH` in an image reference is not a CI/CD variable and must not be substituted as though GitLab would have substituted it.
An empty value is skipped rather than recorded. GitLab exports a defined variable with an empty value, and substituting "" would silently turn `$REGISTRY/app` into `/app` - a resolved-looking reference that is not the one the job uses. Leaving the placeholder in place is what lets the caller see it did not resolve.
func ListMergeRequestNotes ¶ added in v0.1.42
func ListMergeRequestNotes(projectID int, mrIID int, token string, instanceURL string, conf *configuration.Configuration) ([]*gitlab.Note, error)
ListMergeRequestNotes retrieves all notes (comments) on a merge request
func ListProjectBadges ¶ added in v0.1.42
func ListProjectBadges(projectID int, token string, instanceURL string, conf *configuration.Configuration) ([]*gitlab.ProjectBadge, error)
ListProjectBadges retrieves all badges for a project
func ParseDefaultImage ¶
func ParseDefaultImage(conf *GitlabCIConf) (string, error)
ParseDefaultImage parses the default image from a GitLab CI configuration
func ParseGitlabComponentPath ¶ added in v0.3.65
ParseGitlabComponentPath parses a GitLab component path to extract: 1. The instance (if any) 2. The clean path without instance prefix 3. The version (if any)
func ParseGlobalVariables ¶
func ParseGlobalVariables(conf *GitlabCIConf) (map[string]string, error)
ParseGlobalVariables parses global variables of a GitLab CI conf
func ParseJobVariables ¶
ParseJobVariables parses job variables from a GitLab CI conf
func RefResolvesAsTagAndBranch ¶ added in v0.3.70
func RefResolvesAsTagAndBranch(projectPath string, ref string, token string, APIURL string, conf *configuration.Configuration) (tagExists bool, branchExists bool, err error)
RefResolvesAsTagAndBranch probes whether ref exists in projectPath as a tag and/or as a branch. go-gitlab accepts a "group/project" path as the project identifier, so callers pass the include's resolved project path directly. A 404 means "not that kind of ref" (false); any other error is returned so the caller abstains rather than guessing. ref-confusion (ISSUE-402) fires only on a confirmed tag-AND-branch collision, so an indeterminate probe (auth, network, rate limit) must never assert ambiguity — the error path leaves both false and surfaces err.
func ReplaceVariable ¶
func ReplaceVariable(input string, project, group, instance, job, defaultJob, predefined map[string]string) string
ReplaceVariable replaces variables in the input string recursively up to 5 levels
func ResolveLocalIncludes ¶ added in v0.1.41
ResolveLocalIncludes pre-processes a local CI configuration to inline include:local entries from the local filesystem. Other include types (component, template, project, remote) are preserved for GitLab's ciConfig API to resolve server-side.
If the YAML cannot be parsed or no local includes are found, the original content is returned unchanged. If a local include file cannot be read, it is left in the include list for GitLab to resolve from the remote repository.
func ResolveWithinRepo ¶ added in v0.3.87
ResolveWithinRepo joins relPath onto repoRoot and returns the joined path, but only after confirming it does not escape repoRoot. Symlinks are resolved on both sides so a link planted in the checkout cannot disguise an out-of-repo target. It is the shared containment guard for repository- relative paths taken from the analyzed project (include:local targets and the CI config path).
func SearchTags ¶
func SearchTags(projectPath string, token string, APIURL string, conf *configuration.Configuration) ([]string, error, error)
SearchTags gets all tags of a project
func SplitComponentPath ¶ added in v0.4.50
SplitComponentPath splits a component's clean path (no instance, no version) into the project full path and the component name. GitLab component includes are always <project-full-path>/<component-name>, so the project is everything before the final "/": "vendor/components/build" gives "vendor/components" and "build". Used to resolve the project's catalog resource / git tags (#156).
Pair it with ParseGitlabComponentPath, which strips the instance and the version first. Exported because an embedding host otherwise hand-rolls the same split, and a component name taken from the wrong segment silently mismatches the catalogue lookup - the component is then reported as having no published version rather than as up to date.
func ToNormalizedPipeline ¶ added in v0.3.65
func ToNormalizedPipeline( projectPath string, defaultBranch string, ciConfigPath string, origin *GitlabPipelineOriginData, images *GitlabPipelineImageData, protection *GitlabProtectionAnalysisData, variables *GitlabVariablesAnalysisData, securityPolicy *SecurityPolicyData, ) *ir.NormalizedPipeline
ToNormalizedPipeline projects the GitLab collector outputs onto a provider-agnostic IR. Phase 1b: only the fields required by the first rule ported to Rego (image/mutable_tag) are mapped. Additional fields (services, includes, branch protection, etc.) will be filled in as each rule is migrated.
This function is pure: no I/O, no external state. It is safe to call from tests with hand-built fixtures.
func UpdateMergeRequestNote ¶ added in v0.1.42
func UpdateMergeRequestNote(projectID int, mrIID int, noteID int, body string, token string, instanceURL string, conf *configuration.Configuration) (*gitlab.Note, error)
UpdateMergeRequestNote updates an existing note (comment) on a merge request
func UpdateProjectBadge ¶ added in v0.1.42
func UpdateProjectBadge(projectID int, badgeID int, name, imageURL, linkURL, token, instanceURL string, conf *configuration.Configuration) (*gitlab.ProjectBadge, error)
UpdateProjectBadge updates an existing badge on a project
func WrapTransportWithRetry ¶
func WrapTransportWithRetry(transport http.RoundTripper, conf *configuration.Configuration) http.RoundTripper
WrapTransportWithRetry wraps an existing http.RoundTripper with retry logic
Types ¶
type Artifacts ¶
type Artifacts struct {
// NOTE: this type must be verified if we need to use it !
// See https://docs.gitlab.com/ee/ci/yaml/#rules
Paths []string `yaml:"paths,omitempty"`
When string `yaml:"when,omitempty"`
Name string `yaml:"name,omitempty"`
Untracked bool `yaml:"untracked,omitempty"`
}
type BranchProtection ¶
type BranchProtection struct {
ProtectionPattern string `json:"protectionPattern"`
AllowForcePush bool `json:"allowForcePush"`
CodeOwnerApprovalRequired bool `json:"codeOwnerApprovalRequired"`
MinPushAccessLevel int `json:"minPushAccessLevel"`
MinMergeAccessLevel int `json:"minMergeAccessLevel"`
PushAccessLevels []BranchProtectionAccessLevel `json:"pushAccessLevels"`
MergeAccessLevels []BranchProtectionAccessLevel `json:"mergeAccessLevels"`
}
func FetchProjectBranchData ¶
func FetchProjectBranchData(projectPath string, token string, APIURL string, conf *configuration.Configuration) ([]string, []BranchProtection, error)
FetchProjectBranchData fetches branches and their protection settings
type CICDVariable ¶
type CICDVariable struct {
Name string `json:"name"`
Type string `json:"type"`
Environment string `json:"environment"`
Protected bool `json:"protected"`
Masked bool `json:"masked"`
Hidden bool `json:"hidden"`
Value string `json:"value"`
}
Data of Gitlab projects and groups variables
func GetGitlabInstanceVariables ¶
func GetGitlabInstanceVariables(token string, instanceUrl string, conf *configuration.Configuration) ([]CICDVariable, error)
GetGitlabInstanceVariables returns all instance variables
func GetGitlabProjectInheritedVariables ¶
func GetGitlabProjectInheritedVariables(fullPath string, token string, instanceUrl string, conf *configuration.Configuration) ([]CICDVariable, error)
GetGitlabProjectInheritedVariables returns all project inherited variables
func GetGitlabProjectVariables ¶
func GetGitlabProjectVariables(fullPath string, token string, instanceUrl string, conf *configuration.Configuration) ([]CICDVariable, error)
GetGitlabProjectVariables returns all project variables
type CICDVariableConf ¶
type CICDVariableSource ¶
type CICatalogResource ¶
type CICatalogResource struct {
ID string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Topics []string `json:"topics"`
VerificationLevel string `json:"verificationLevel"`
VisibilityLevel string `json:"visibilityLevel"`
StarCount int `json:"starCount"`
Icon string `json:"icon"`
FullPath string `json:"fullPath"`
Last30DayUsageCount int `json:"last30DayUsageCount"`
LatestReleasedAt string `json:"latestReleasedAt"`
WebPath string `json:"webPath"`
Versions []CICatalogResourceVersion `json:"versions"`
}
func GetGitlabCIComponentResource ¶ added in v0.3.60
func GetGitlabCIComponentResource(fullPath string, token string, instanceUrl string, conf *configuration.Configuration) (*CICatalogResource, error)
GetGitlabCIComponentResource fetches a SINGLE CI/CD catalog resource by its project full path, with its released versions and their components. It is the targeted replacement for the removed instance-wide catalog enumeration: on a large catalog (gitlab.com has ~800 resources) that broad query returns a multi-megabyte payload that exceeds the HTTP timeout, gets cancelled, and silently disables outdated-include detection (#156). This per-component lookup returns in well under a second and is complete (no pagination roulette). Returns (nil, nil) when no catalog resource exists at fullPath — e.g. a component published only as git tags, or a plain project include — so the caller can fall back to the tags API.
type CICatalogResourceVersion ¶
type CICatalogResourceVersion struct {
Name string `json:"name"`
Path string `json:"path"`
Components []CIComponent `json:"components"`
}
type CIComponent ¶
type CIConfDefault ¶
type CIConfDefault struct {
Image interface{} `yaml:"image,omitempty"`
}
type CIConfVariable ¶
type Cache ¶
type Cache struct {
// NOTE: this type must be verified if we need to use it !
// See https://docs.gitlab.com/ee/ci/yaml/#rules
Key interface{} `yaml:"key,omitempty"`
Paths []string `yaml:"paths,omitempty"`
Policy string `yaml:"policy,omitempty"`
When string `yaml:"when,omitempty"`
Untracked bool `yaml:"untracked,omitempty"`
}
type Environment ¶
type Environment struct {
// NOTE: this type must be verified if we need to use it !
// See https://docs.gitlab.com/ee/ci/yaml/#rules
Name map[string]string `yaml:",inline"`
URL string `yaml:"url,omitempty"`
}
type Except ¶
type Except struct {
// NOTE: this type must be verified if we need to use it !
// See https://docs.gitlab.com/ee/ci/yaml/#rules
Refs []string `yaml:"refs,omitempty"`
Kinds []string `yaml:"kinds,omitempty"`
Variables map[string]string `yaml:"variables,omitempty"`
}
type GitlabCIConf ¶
type GitlabCIConf struct {
Image interface{} `yaml:"image,omitempty"`
GlobalVariables map[string]interface{} `yaml:"variables,omitempty"`
Stages []string `yaml:"stages,omitempty"`
BeforeScript interface{} `yaml:"before_script,omitempty"`
AfterScript interface{} `yaml:"after_script,omitempty"`
DefaultScript interface{} `yaml:"script,omitempty"`
Default CIConfDefault `yaml:"default,omitempty"`
Spec interface{} `yaml:"spec,omitempty"`
Include IncludeList `yaml:"include,omitempty"` // Can be list of string or list of include
GitlabJobs map[string]interface{} `yaml:",inline"` // Can be a string or a map[string]GitlabJob
Workflow interface{} `yaml:"workflow,omitempty"`
Cache interface{} `yaml:"cache,omitempty"`
}
GitLab CI Configuration
type GitlabJob ¶
type GitlabJob struct {
Script interface{} `yaml:"script,omitempty"` // Can be both multi lines or one literal block scalar
BeforeScript interface{} `yaml:"before_script,omitempty"` // Can be both multi lines or one literal block scalar
AfterScript interface{} `yaml:"after_script,omitempty"` // Can be both multi lines or one literal block scalar
Stage string `yaml:"stage,omitempty"`
Image interface{} `yaml:"image,omitempty"`
Services interface{} `yaml:"services,omitempty"` // Can be both a list of string or a list of Serive
Only interface{} `yaml:"only,omitempty"`
Except interface{} `yaml:"except,omitempty"`
Variables map[string]interface{} `yaml:"variables,omitempty"`
Cache interface{} `yaml:"cache,omitempty"`
Dependencies interface{} `yaml:"dependencies,omitempty"`
Needs interface{} `yaml:"needs,omitempty"`
Rules interface{} `yaml:"rules,omitempty"`
Artifacts interface{} `yaml:"artifacts,omitempty"`
Environment interface{} `yaml:"environment,omitempty"`
When interface{} `yaml:"when,omitempty"`
AllowFailure interface{} `yaml:"allow_failure,omitempty"`
Extends interface{} `yaml:"extends,omitempty"`
}
func ParseGitlabCIJob ¶
ParseGitlabCIJob parses a job from GitLab CI conf
type GitlabPipelineImageData ¶ added in v0.3.65
type GitlabPipelineImageData struct {
// Gitlab CI configuration
MergedConf *GitlabCIConf
CiValid bool
CiMissing bool
// Default image and variables
DefaultImage string
InstanceVars map[string]string
GroupVars map[string]string
ProjectVars map[string]string
GlobalVars map[string]string
// Images found in the pipeline
Images []GitlabPipelineImageInfo `json:"images"`
}
type GitlabPipelineImageDataCollection ¶ added in v0.3.65
type GitlabPipelineImageDataCollection struct{}
func (*GitlabPipelineImageDataCollection) Run ¶ added in v0.3.65
func (dc *GitlabPipelineImageDataCollection) Run(project *ProjectInfo, token string, conf *configuration.Configuration, pipelineOriginData *GitlabPipelineOriginData) (*GitlabPipelineImageData, *GitlabPipelineImageMetrics, error)
type GitlabPipelineImageInfo ¶ added in v0.3.65
type GitlabPipelineImageInfo struct {
Link string `json:"link"`
Name string `json:"image"`
Tag string `json:"tag"`
Registry string `json:"registry"`
Job string `json:"job"`
// Unresolved records that the reference still contained a `$VARIABLE`
// after substitution, so the registry, name and tag below were parsed
// out of a placeholder rather than out of an image reference.
//
// This is not a small imprecision. `$CI_REGISTRY_IMAGE:$TAG` parses to
// the "unknown" registry and either an empty tag or the literal string
// "$TAG", and the rules then answer real questions about it: whether the
// registry is on the trusted list, whether the tag is forbidden. Both
// answers are arbitrary. Marking the reference lets the rules abstain on
// that one job and keep judging every other one.
Unresolved bool `json:"unresolved,omitempty"`
}
type GitlabPipelineImageMetrics ¶ added in v0.3.65
type GitlabPipelineJobData ¶ added in v0.3.65
type GitlabPipelineJobGitlabComponent ¶ added in v0.3.65
type GitlabPipelineJobGitlabComponent struct {
RepoFullPath string `json:"repoFullPath"`
RepoWebPath string `json:"repoWebPath"`
RepoName string `json:"repoName"`
ComponentName string `json:"componentName"`
ComponentLatestVersion string `json:"componentLatestVersion"`
ComponentIncludePath string `json:"componentIncludePath"`
}
GitlabPipelineJobGitlabComponent represents a GitLab component
type GitlabPipelineJobPlumberOrigin ¶ added in v0.3.65
type GitlabPipelineJobPlumberOrigin struct {
ID uint `json:"id"`
Path string `json:"path"`
LatestVersion string `json:"latestVersion"`
}
GitlabPipelineJobPlumberOrigin represents a Plumber template origin
type GitlabPipelineOriginData ¶ added in v0.3.65
type GitlabPipelineOriginData struct {
// Gitlab CI configuration
Conf *GitlabCIConf
ConfString string
MergedConf *GitlabCIConf
MergedResponse *MergedCIConfResponse
CiValid bool
CiMissing bool
CiErrors []string // Specific CI config errors for output
IncludesFailed []string // include locations whose fetch failed (jobs dropped from analysis, #220)
// RefProbesFailed names the includes whose tag-vs-branch ambiguity probe
// could not be completed.
//
// The probe is fail-safe by design: only a CONFIRMED tag-and-branch
// double hit sets RefIsAmbiguous, so a probe that errors leaves the flag
// false. That is the right default for the flag and the wrong answer for
// the report, because false reads as "this ref is unambiguous" - a pass
// the run has no evidence for. Recording the failures lets the caller
// mark the control not_evaluable instead of certifying a ref it never
// managed to look up.
RefProbesFailed []string
// VersionLookupsFailed names the includes whose LATEST upstream version
// could not be looked up - the component catalogue query, or the tag
// listing on a versioned project include.
//
// Same shape of hazard as RefProbesFailed and the same reason for
// recording it. A failed lookup leaves Current empty, and the
// up-to-date rule requires a non-empty Current, so the include is
// silently skipped and the control reports a clean pass over includes it
// never compared against anything. These queries hit the include's
// SOURCE project, so they are among the first to fail for a token scoped
// to the analyzed project.
VersionLookupsFailed []string
// RawConfigUnavailable records that the project's own UNMERGED CI file
// could not be read, while the merged pipeline was obtained anyway.
//
// Two controls read the pre-merge document by design, and both fail
// SILENTLY without it: the hardcoded-job map comes up empty, so every
// job reads as contributed by an include, and the local-variable
// comparison has nothing to compare. Neither produces a finding, so
// both would report a clean pass over a document nobody read.
LimitedAnalysis bool
// Origins and jobs data
Origins []GitlabPipelineOriginDataFull
// CI conf content
JobMap map[string]*GitlabPipelineJobData
JobExtendsMap map[string][]string
JobHardcodedMap map[string]bool
JobHardcodedContent map[string]interface{}
}
type GitlabPipelineOriginDataCollection ¶ added in v0.3.65
type GitlabPipelineOriginDataCollection struct{}
func (*GitlabPipelineOriginDataCollection) Run ¶ added in v0.3.65
func (dc *GitlabPipelineOriginDataCollection) Run(project *ProjectInfo, token string, conf *configuration.Configuration) (*GitlabPipelineOriginData, *GitlabPipelineOriginMetrics, error)
type GitlabPipelineOriginDataFull ¶ added in v0.3.65
type GitlabPipelineOriginDataFull struct {
// Origin data generic and specific
GitlabPipelineOriginDataGeneric
GitlabPipelineOriginDataProjectSpecific
}
type GitlabPipelineOriginDataGeneric ¶ added in v0.3.65
type GitlabPipelineOriginDataGeneric struct {
OriginType string `json:"originType"`
FromPlumber bool `json:"fromPlumber"`
FromGitlabCatalog bool `json:"fromGitlabCatalog"`
PlumberOrigin GitlabPipelineJobPlumberOrigin `json:"plumberOrigin"`
GitlabIncludeOrigin IncludeOriginWithoutRef `json:"gitlabIncludeOrigin"`
GitlabComponent GitlabPipelineJobGitlabComponent `json:"gitlabComponent"`
OriginHash uint64 `json:"originHash"`
}
type GitlabPipelineOriginDataProjectSpecific ¶ added in v0.3.65
type GitlabPipelineOriginDataProjectSpecific struct {
// Data specific to this project
Version string `json:"version"`
UpToDate bool `json:"upToDate"`
Nested bool `json:"nested"`
// RefIsAmbiguous: the pinned Version resolves upstream as both a
// tag and a branch (ref-confusion, ISSUE-402). Set by the origin
// collector's tag+branch probe; false unless both are confirmed.
RefIsAmbiguous bool `json:"refIsAmbiguous"`
// Job related data
Jobs []GitlabPipelineJobData `json:"jobs"`
}
type GitlabPipelineOriginMetrics ¶ added in v0.3.65
type GitlabPipelineOriginMetrics struct {
// Data metrics: jobs
JobTotal uint `json:"jobTotal"`
JobHardcoded uint `json:"jobHardcoded"`
// Data metrics: origin
OriginTotal uint `json:"originTotal"`
OriginComponent uint `json:"originComponent"`
OriginLocal uint `json:"originLocal"`
OriginProject uint `json:"originProject"`
OriginRemote uint `json:"originRemote"`
OriginTemplate uint `json:"originTemplate"`
OriginGitLabCatalog uint `json:"originGitLabCatalog"`
OriginOutdated uint `json:"originOutdated"`
}
type GitlabProtectionAnalysisData ¶ added in v0.3.65
type GitlabProtectionAnalysisData struct {
Branches []string `json:"branches"`
BranchProtections []BranchProtection `json:"branchProtections"`
// BranchProtectionsKnown records whether the protection listing was read
// authoritatively. False on a 403 or any other failure, so the branch
// controls report not-evaluable rather than reading an unreadable
// listing as "this project protects nothing" - which is the precise
// violation they exist to catch, and so the most damaging thing to
// fabricate.
//
// The branch NAMES survive a protection failure, so the two facts are
// tracked separately: the run still knows which branches exist.
BranchProtectionsKnown bool `json:"branchProtectionsKnown"`
MRApprovalRules []*glab.ProjectApprovalRule `json:"mrApprovalRules"`
// MRApprovalRulesKnown records whether the approval-rules listing was
// read authoritatively. It stays false on a 403/404 (non-premium
// GitLab, or a token without scope), so the approval-rule controls
// (ISSUE-502/504) report not-evaluable rather than a false pass: an
// unreadable listing must not make a project look compliant.
MRApprovalRulesKnown bool `json:"mrApprovalRulesKnown"`
MRApprovalSettings *glab.ProjectApprovals `json:"mrApprovalSettings"`
MRSettings *glab.Project `json:"mrSettings"`
}
GitlabProtectionAnalysisData holds all the data needed by protection controls
func ProtectionFromSnapshot ¶ added in v0.4.50
func ProtectionFromSnapshot(run *platform.RunContext) (*GitlabProtectionAnalysisData, bool)
ProtectionFromSnapshot builds the protection collection out of the platform's snapshot, for a run whose lanes the platform has taken over.
The second return is false in standalone mode - and whenever the context fetch itself failed - so the caller collects from GitLab exactly as it always has. It is never false merely because a lane is empty: once the platform has answered, its answer is the lane, including "nothing here".
MRSettings comes from the project_details lane, which carries the project payload's merge settings (mergeRequestSettingsMustBeCompliant / ISSUE-506) since 2026-08-28. It stays nil when that lane is absent, degraded, or predates the merge settings - see mrSettingsFromSnapshot for why a partial lane is treated as no lane at all.
type GitlabProtectionData ¶ added in v0.3.65
type GitlabProtectionData struct {
Branches []*GitlabProtectionDataBranch `json:"branches"`
}
GitlabProtectionData holds the collected protection data
type GitlabProtectionDataBranch ¶ added in v0.3.65
type GitlabProtectionDataBranch struct {
BranchName string `json:"branchName"`
Default bool `json:"default"`
}
GitlabProtectionDataBranch holds branch information
type GitlabProtectionDataCollection ¶ added in v0.3.65
type GitlabProtectionDataCollection struct{}
GitlabProtectionDataCollection handles protection data collection
func (*GitlabProtectionDataCollection) Run ¶ added in v0.3.65
func (dc *GitlabProtectionDataCollection) Run( project *ProjectInfo, token string, conf *configuration.Configuration, ) (*GitlabProtectionAnalysisData, *GitlabProtectionMetrics, error)
Run fetches all GitLab protection data needed by the controls
type GitlabProtectionMetrics ¶ added in v0.3.65
type GitlabProtectionMetrics struct {
Branches int `json:"branches"`
}
GitlabProtectionMetrics holds metrics about protection data
type GitlabVariablesAnalysisData ¶ added in v0.4.41
type GitlabVariablesAnalysisData struct {
Variables []CICDVariable
Known bool
}
GitlabVariablesAnalysisData holds the project's settings CI/CD variables (GitLab: Settings > CI/CD > Variables) with their security flags, for the cicdVariablesMustBeProtected / cicdVariablesMustBeMasked controls.
Known records whether the listing was read authoritatively. A 401/403 (or any other settings-API failure) leaves it false, so the controls report not-evaluable rather than a false pass: a token that cannot read the variables must not make an unprotected variable look protected (#418).
func CollectGitlabVariables ¶ added in v0.4.41
func CollectGitlabVariables(fullPath, token string, conf *configuration.Configuration) (*GitlabVariablesAnalysisData, error)
CollectGitlabVariables fetches the project's settings CI/CD variables with their protected/masked flags. Any fetch failure — most importantly a 401/403 from a token without the variable-read scope — is a definitive "cannot evaluate", never a false pass: Variables stays empty and Known stays false. The variable values are fetched but never projected onto the IR (see gitlab_ir.go::buildSettingsVariables), per the #370 variable-sensitivity tiers.
The fetch error is also returned (alongside the always-non-nil data) so the caller can distinguish a transient network failure — which must degrade the run (exit 3), like the branch/image collectors (#220) — from a definitive permission failure (401/403 or a null project), which stays a plain not-evaluable. Known is false in both cases.
func VariablesFromSnapshot ¶ added in v0.4.50
func VariablesFromSnapshot(run *platform.RunContext) (*GitlabVariablesAnalysisData, bool)
VariablesFromSnapshot builds the settings-variable collection out of the platform's snapshot, filtered to the project's OWN variables.
The second return follows ProtectionFromSnapshot: false only in standalone mode.
Known is false when the platform reports the variables lane as a failed collection, so cicdVariablesMustBeProtected / ...MustBeMasked report not-evaluable instead of certifying an unprotected variable as fine. It is TRUE for a healthy collection that found nothing, which is a real answer: a project with no CI/CD variables passes both controls.
type Group ¶
type Group struct {
IdOnPlatform int `json:"idOnPlatform" validate:"required,number"`
GroupIdOnPlatform int `json:"groupIdOnPlatform" validate:"number"`
Path string `json:"path" validate:"required,max=300"`
Name string `json:"name" validate:"required,max=300"`
Visibility string `json:"visibility" validate:"required,max=50"`
CreatedAt time.Time `json:"createdAt"`
}
Data of a GitLab group
type GroupMetadataNode ¶
type GroupProjectsResponse ¶
type GroupProjectsResponse struct {
Group struct {
Projects struct {
Nodes []ProjectMetadataNode
PageInfo PageInfo
}
}
}
Gitlab GraphQL response of query to get all projects of a group with metadata
type Image ¶
type Image struct {
Name string `yaml:"name,omitempty"`
Entrypoint []string `yaml:"entrypoint,omitempty"`
PullPolicy StringOrSlice `yaml:"pull_policy,omitempty"`
}
type IncludeJobs ¶ added in v0.4.50
type IncludeJobs struct {
// Jobs the include contributed, by name.
Jobs []string
// Known reports whether the attribution was established. False means the
// include could not be resolved, and the caller must NOT read the empty
// Jobs as "this include contributed nothing": the jobs it did contribute
// are still in the merged pipeline with nothing attributing them
// upstream, so rules keyed on that distinction fire on them as though the
// project had written them.
Known bool
// Nested marks an include pulled in by another include rather than by
// this project. Its jobs are attributed to the include that pulled it in,
// so it contributes none at this level: an empty Jobs with Known true.
Nested bool
}
IncludeJobs is one include's attribution. Returned one per request include, in the same order.
func DeriveIncludeJobs ¶ added in v0.4.50
func DeriveIncludeJobs(req IncludeJobsRequest) ([]IncludeJobs, error)
DeriveIncludeJobs answers "which jobs did each include contribute" for every include in the request, in order.
This is the CLI's own attribution, exported whole so an embedding host does not reimplement the identification around it. It makes one config-merge request per non-nested include, against the ANALYSED project rather than the include's source, and reads the job names out of the result.
An include that cannot be resolved yields Known false rather than an error: one unreachable include must not cost the caller the attribution of every other one. The returned error is reserved for a request that could not be started at all.
type IncludeJobsRequest ¶ added in v0.4.50
type IncludeJobsRequest struct {
// RawConfig is the project's OWN unmerged CI configuration - the file as
// written, not the merged document. The inputs an include is called with
// only exist there: the merged result has them already applied.
RawConfig *GitlabCIConf
// Includes is the merged response's include list. The result is returned
// in THIS order and the index is the join key.
Includes []MergedCIConfResponseInclude
// Stages from the MERGED configuration. A component may reference a stage
// defined at the root, and an include re-merged without them fails to
// resolve.
Stages []string
// ProjectPath is the project being analysed, and is what decides whether
// an include is nested: an include whose ContextProject differs was
// pulled in by another include, not by this project.
ProjectPath string
Token string
APIURL string
// SHA the includes are resolved at.
SHA string
Conf *configuration.Configuration
}
IncludeJobsRequest carries what job attribution needs. Every field comes from a collection the caller has already made; nothing here re-fetches the pipeline.
type IncludeList ¶ added in v0.2.8
type IncludeList []interface{}
IncludeList is a type that can unmarshal from either a scalar value or a slice. GitLab CI accepts both forms:
- include: "https://..." (scalar string)
- include: (sequence)
- "https://..."
- remote: "https://..."
- project: foo file: bar.yml
When GitLab serializes the merged CI configuration it may normalize a single-item array into a scalar, which the plain []interface{} field cannot handle. This type absorbs both representations transparently.
func (*IncludeList) UnmarshalYAML ¶ added in v0.2.8
func (il *IncludeList) UnmarshalYAML(unmarshal func(interface{}) error) error
UnmarshalYAML implements yaml.v2 Unmarshaler interface
type IncludeOrigin ¶
type IncludeOrigin struct {
IncludeOriginWithoutRef
Raw string `json:"raw"`
Ref string `json:"ref"`
}
type IncludeOriginWithoutRef ¶
type InstanceGroupsResponse ¶
type InstanceGroupsResponse struct {
Groups struct {
Nodes []GroupMetadataNode
PageInfo PageInfo
}
}
Gitlab GraphQL response of query to get all groups of an instance with metadata
type InstanceProjectsResponse ¶
type InstanceProjectsResponse struct {
Projects struct {
Nodes []ProjectMetadataNode
PageInfo PageInfo
}
}
Gitlab GraphQL response of query to get all projects of an instance with metadata
type MergedCIConfResponse ¶
type MergedCIConfResponse struct {
CiConfig struct {
MergedYaml string `json:"mergedYaml"`
Errors []string `json:"errors"`
Warnings []interface{} `json:"warnings"`
Status string `json:"status"`
Includes []MergedCIConfResponseInclude `json:"includes"`
Stages struct {
Nodes []struct {
Name string `json:"name"`
Groups struct {
Nodes []struct {
Name string `json:"name"`
Size int `json:"size"`
Jobs struct {
Nodes []struct {
Name string `json:"name"`
Script []string `json:"script"`
} `json:"nodes"`
} `json:"jobs"`
} `json:"nodes"`
} `json:"groups"`
} `json:"nodes"`
} `json:"stages"`
} `json:"ciConfig"`
}
Gitlab GraphQL response of merged CI conf
func FetchGitlabMergedCIConf ¶
func FetchGitlabMergedCIConf(projectPath string, confContent string, sha string, userToken string, instanceUrl string, conf *configuration.Configuration) (MergedCIConfResponse, error)
FetchGitlabMergedCIConf gets merged version of a GitLab CI configuration
type MergedCIConfResponseInclude ¶
type MergedCIConfResponseInclude struct {
Location string `json:"location,omitempty"`
Raw string `json:"raw,omitempty"`
Blob string `json:"blob,omitempty"` // Contains version-specific reference (e.g., blob SHA) - critical for cache key differentiation
ContextProject string `json:"contextProject,omitempty"`
Type string `json:"type,omitempty"`
Extra struct {
Project string `json:"project,omitempty"`
Ref string `json:"ref,omitempty"`
} `json:"extra,omitempty"`
// RefExistsAsTag and RefExistsAsBranch report whether this include's ref
// names an existing tag, and an existing branch, in the source project.
//
// Tri-state deliberately. A nil pointer means the host did not determine
// the answer - a skipped probe, a rate limit, a cancelled request - which
// is NOT a determined false and must not be read as one. A ref that could
// not be checked is not an unambiguous ref, and collapsing the two is the
// silent pass ISSUE-402 exists to catch.
RefExistsAsTag *bool `json:"ref_exists_as_tag,omitempty"`
RefExistsAsBranch *bool `json:"ref_exists_as_branch,omitempty"`
// Jobs is the list of job names this include contributed, and JobsKnown
// whether that was established.
//
// The CLI derives this itself with one config-merge request per include
// (DeriveIncludeJobs). A host that has already done so serves it here and
// the request is skipped.
//
// JobsKnown is the discriminator, not the emptiness of Jobs: an empty
// list is a REAL answer (a nested include, or one contributing only
// variables), so it cannot double as "we did not find out". Jobs is read
// only when JobsKnown is true; anything else falls through to the CLI's
// own resolution, and if that cannot run the include controls degrade
// rather than treating an unresolved include as one that contributed
// nothing.
Jobs []string `json:"jobs,omitempty"`
JobsKnown bool `json:"jobs_known,omitempty"`
// SourceCatalog is the CI catalogue listing for the include's source
// project, exactly as GetGitlabCIComponentResource returns it: every
// published version and the components each one carries.
//
// It is served verbatim rather than reduced to a "latest version" on
// purpose. Which versions count is a rule - only those still carrying
// the named component - and latestCatalogVersion applies it here. A host
// that reduces first has to reimplement that rule to do so, and a
// component dropped in a later version is then reported as upgradeable
// to a version that does not contain it.
//
// Nil means the lookup did not complete, which leaves the component with
// no known latest version and the up-to-date control without a verdict.
SourceCatalog *CICatalogResource `json:"source_catalog,omitempty"`
}
type Only ¶
type Only struct {
// NOTE: this type must be verified if we need to use it !
// See https://docs.gitlab.com/ee/ci/yaml/#rules
Refs []string `yaml:"refs,omitempty"`
Kinds []string `yaml:"kinds,omitempty"`
Variables map[string]string `yaml:"variables,omitempty"`
}
type Project ¶
type Project struct {
IdOnPlatform int `json:"idOnPlatform" validate:"required,number"`
GroupIdOnPlatform int `json:"groupIdOnPlatform" validate:"required,number"`
Path string `json:"path" validate:"required,max=300"`
Name string `json:"name" validate:"required,max=300"`
Visibility string `json:"visibility" validate:"required,max=50"`
DefaultBranch string `json:"defaultBranch" validate:"max=100"`
CiConfPath string `json:"ciConfPath" validate:"required,max=100"`
LastActivityAt time.Time `json:"lastActivityAt" validate:"required"`
Archived bool `json:"archived"`
LatestHeadCommitSha string `json:"latestHeadCommitSha"`
IsCatalogResource bool `json:"isCatalogResource"`
//Note: IsOfficialCatalogResource is not returned by gitlab, we set it ourselves
IsOfficialCatalogResource bool `json:"isOfficialCatalogResource"`
Languages []ProjectLanguage `json:"languages"`
CreatedAt time.Time `json:"createdAt" validate:"required"`
// The merge-request settings mergeRequestSettingsMustBeCompliant
// (ISSUE-506) compares against. They come from the same
// Projects.GetProject response as everything above, so carrying them
// costs no extra request - they were simply not projected before.
//
// The Plumber platform imports this package to build its own collector
// and cannot serve a project_details lane for ISSUE-506 without them
// (#368 ask 4). MergeMethod and SquashOption are GitLab typed strings
// upstream; they are plain strings here because nothing in this repo
// compares them as anything else.
MergeMethod string `json:"mergeMethod"`
SquashOption string `json:"squashOption"`
MergePipelinesEnabled bool `json:"mergePipelinesEnabled"`
MergeTrainsEnabled bool `json:"mergeTrainsEnabled"`
AllowMergeOnSkippedPipeline bool `json:"allowMergeOnSkippedPipeline"`
ResolveOutdatedDiffDiscussions bool `json:"resolveOutdatedDiffDiscussions"`
PrintingMergeRequestLinkEnabled bool `json:"printingMergeRequestLinkEnabled"`
RemoveSourceBranchAfterMerge bool `json:"removeSourceBranchAfterMerge"`
}
Data of a GitLab project
func FetchProjectDetails ¶
func FetchProjectDetails(projectPath string, token string, instanceURL string, conf *configuration.Configuration) (*Project, error)
FetchProjectDetails fetches complete project information from GitLab API and returns a Project struct populated with all available data
func ProjectFromCIEnvironment ¶ added in v0.4.50
ProjectFromCIEnvironment builds the analyzed project's identity from the predefined variables GitLab defines in every job, making no API call.
analyzed is the project this run is REPORTING on, and the environment is only accepted when it describes that same project. The two are not always the same: `plumber analyze --project other/group/repo` is supported from inside a CI job, and there the environment describes the runner's project instead. Taking it anyway would collect branch protections, variables and a CI configuration from the runner's project and file them under the other one's name - a whole report about the wrong repository, with no field left inconsistent for anything downstream to catch.
The second return is false whenever the environment cannot answer - outside CI, in a job missing the variables this needs, or for a different project - and the caller falls back to the API. It is never a partial answer: an identity assembled half from the environment and half from defaults would be wrong in a way nothing downstream could detect.
ciConfigPath is what the platform's snapshot reported, and it wins over $CI_CONFIG_PATH when set. The platform anchored its own config digest against that value, so digesting against anything else can never match.
Only call this in platform mode. GroupIdOnPlatform below is left zero because no predefined variable carries a namespace KIND, and the one reader of the ProjectInfo.IsGroup it feeds is a code path platform mode never reaches.
func (*Project) ToProjectInfo ¶
func (p *Project) ToProjectInfo() *ProjectInfo
ToProjectInfo converts Project to the simpler ProjectInfo struct used by collectors
type ProjectBranchesResponse ¶
type ProjectBranchesResponse struct {
Project struct {
Repository struct {
BranchNames []string
}
}
}
Gitlab GrapQL response of query to get all branches of a project
type ProjectInfo ¶
type ProjectInfo struct {
ID int // Project ID on GitLab
Path string
CiConfPath string
DefaultBranch string // The actual default branch from GitLab (e.g., "main")
AnalyzeBranch string // The branch to analyze (from --branch flag, defaults to DefaultBranch)
LatestHeadCommitSha string
Archived bool
NotFound bool
IsGroup bool // True if organization is a group (vs instance-wide)
}
ProjectInfo contains basic project information for CI analysis
type ProjectLanguage ¶
type ProjectLanguage struct {
Name string `json:"name"`
}
ProjectLanguage represents a programming language used in a project
type ProjectMetadataNode ¶
type ProjectMetadataNode struct {
ID string
CreatedAt time.Time
NameWithNamespace string
FullPath string
Visibility string
CiConfigPathOrDefault string
Repository struct {
RootRef string
Tree struct {
LastCommit struct {
Sha string
}
}
}
Group struct {
ID string
}
LastActivityAt time.Time
Archived bool
IsCatalogResource bool
Languages []struct {
Name string `json:"name"`
Share float64 `json:"share"`
}
}
type RetryConfig ¶
type RetryConfig struct {
MaxRetries int
InitialBackoff time.Duration
MaxBackoff time.Duration
BackoffFactor float64
}
RetryConfig holds the configuration for retry logic
func DefaultRetryConfig ¶
func DefaultRetryConfig(conf *configuration.Configuration) *RetryConfig
DefaultRetryConfig returns the default retry configuration
type Rule ¶
type Rule struct {
// NOTE: this type must be updated if we need to use it !
// See https://docs.gitlab.com/ee/ci/yaml/#rules
If string `yaml:"if"`
ChangesFrom []string `yaml:"changes"`
When string `yaml:"when"`
AllowFailure bool `yaml:"allow_failure"`
}
type SecurityPolicyData ¶ added in v0.4.44
type SecurityPolicyData struct {
// Known is true when the linkage was read authoritatively. A nil Project
// then means "none linked", a real state the rule fires on. False means
// the read failed (auth error, null project, or the field is unavailable
// on this instance), so ISSUE-601 reports not-evaluable, not a false pass.
Known bool
// Project is the linked security policy project, or nil when none is
// linked. Only meaningful when Known is true.
Project *SecurityPolicyProjectLink
}
SecurityPolicyData is the collected security-policy-project linkage for a run. It is deliberately its own collection rather than a field on GitlabProtectionAnalysisData: the linkage is read over GraphQL, a separate API surface from the REST protection endpoints, and folding it in made ISSUE-601 hostage to them. A token that cannot list branches aborts the protection collection before the GraphQL read is ever reached, which left the control reporting not-evaluable forever on a linkage it could have read perfectly well.
func CollectSecurityPolicy ¶ added in v0.4.44
func CollectSecurityPolicy(fullPath, token, instanceUrl string, conf *configuration.Configuration) (*SecurityPolicyData, error)
CollectSecurityPolicy reads the project's security-policy-project linkage. The returned error is the transport/API failure, if any: the caller decides whether it degrades the run (a network blip should not read as a clean pass) while the returned data already carries Known=false so the control reports not-evaluable either way.
func SecurityPolicyFromSnapshot ¶ added in v0.4.57
func SecurityPolicyFromSnapshot(run *platform.RunContext) (*SecurityPolicyData, bool)
SecurityPolicyFromSnapshot builds the security-policy-project linkage (projectMustHaveSecurityPolicySource / ISSUE-601) out of the platform's snapshot, and reports whether the platform served that lane at all.
A false second return means the run has NO linkage data: standalone mode and a context that was never fetched (collect it locally, as always), and - in platform mode - an absent or degraded lane, where the caller leaves the collection nil and the control reports not_evaluable. The runner does not fall back to GraphQL for it: a CI job token cannot read that field, so the request could only spend a credential to fail.
Known is carried VERBATIM, never upgraded. The platform's three shapes each mean something different to the rule, and only one of them is a verdict:
- Known with a linked project: the linkage exists, and the rule checks it against the configured expectation.
- Known alone: the linkage was read authoritatively and nothing is linked. That is the real Critical ISSUE-601 exists to report, not an absence.
- Known false: the read was not authoritative (an auth failure, a null GraphQL project, or the field being unavailable on this instance). The projection then abstains, so the control reports not_evaluable rather than certifying an unread project as linked or unlinked.
Project is set only when Known AND an id was served. An id alongside Known false is not a linkage the run may report on, and an absent id is never a real project id of 0.
type SecurityPolicyProject ¶
type SecurityPolicyProjectLink ¶ added in v0.4.44
type SecurityPolicyProjectLink struct {
// ID is the numeric project ID of the linked security policy project.
ID int
// FullPath is its namespace/path.
FullPath string
}
SecurityPolicyProjectLink is the GitLab security policy project linked to the analysed project. GitLab Ultimate: a project points at a single security policy project that carries the org's scan-execution and merge-request approval policies.
func GetSecurityPolicyProject ¶ added in v0.4.44
func GetSecurityPolicyProject(fullPath, token, instanceUrl string, conf *configuration.Configuration) (*SecurityPolicyProjectLink, bool, error)
GetSecurityPolicyProject fetches the project's linked security policy project via GraphQL. It returns:
- (link, true, nil) on a successful read where a policy project is linked;
- (nil, true, nil) on a successful read where NONE is linked (the GitLab-Free/Ultimate-but-unlinked case — the field answers null);
- (nil, false, err) when the linkage could not be read authoritatively (an auth error, or the field is unavailable on the instance). The bool is the "known" flag: a false known maps to not-evaluable, never a false pass.
Security policies require GitLab Ultimate. On a non-Ultimate project the field answers null (no linkage), which is indistinguishable from an Ultimate project that simply has not linked one — the caller surfaces a conditional tier caveat rather than asserting the tier.
type StringOrSlice ¶
type StringOrSlice []string
StringOrSlice is a type that can unmarshal from either a string or a slice of strings This is needed for GitLab CI fields like pull_policy that support both formats:
- pull_policy: "always"
- pull_policy: [if-not-present, always]
- pull_policy:
- if-not-present
- always
func (*StringOrSlice) UnmarshalYAML ¶
func (s *StringOrSlice) UnmarshalYAML(unmarshal func(interface{}) error) error
UnmarshalYAML implements yaml.v2 Unmarshaler interface
type Workflow ¶
type Workflow struct {
// NOTE: this type must be verified if we need to use it !
// See https://docs.gitlab.com/ee/ci/yaml/#rules
Rules interface{} `yaml:"rules,omitempty"`
}
Source Files
¶
- badge.go
- ci_environment.go
- ci_project.go
- ci_variables.go
- client.go
- dataCollectionGitlabPipelineImage.go
- dataCollectionGitlabPipelineOrigin.go
- dataCollectionGitlabProtection.go
- dataCollectionGitlabVariables.go
- gitlab.go
- gitlab_ir.go
- include_jobs.go
- include_observations.go
- logger.go
- models.go
- mrcomment.go
- project.go
- request.go
- response.go
- rest.go
- retry.go
- security_policy.go
- snapshot.go
- utils.go
- utilsCI.go