Post

Build Ecosystems by Programming Language: Tools, Scanners, Frameworks and Files

A DevOps architect's and engineer's reference to the build tools, scan tools, frameworks and build files used by each major programming language.

Build Ecosystems by Programming Language: Tools, Scanners, Frameworks and Files

Every language brings its own build ecosystem: a build tool, a package manager, a lockfile, a set of linters, a test framework and a list of scanners that understand its dependency graph. A DevOps architect has to standardise pipelines across all of them; a DevOps engineer has to make each one build, test and scan reliably in CI. This post is a single reference for both: for each common language it lists the build tools, scan tools, frameworks, the files each build tool expects, one command per tool category and a minimal build file.

Index

The generic build pipeline

The tools change per language, but the stages do not. Each language section below maps its tools onto these stages.

  1. Source + lockfile: A commit triggers the build. The lockfile pins every dependency version so each run resolves the same graph.
  2. Restore dependencies: Are dependencies pinned and reachable? The package manager restores them from the lockfile, ideally through a private registry proxy.
  3. Lint and format check: Does the code follow the agreed style and avoid obvious bugs? Linters, formatters and type checkers fail fast and cheaply.
  4. Compile / bundle: Does it build, reproducibly? The compiler, build tool or bundler produces the build output.
  5. Unit tests + coverage: Does it behave correctly, and how much is covered? The test framework runs and a coverage report is produced.
  6. Security scans in parallel: SAST checks our code for vulnerable patterns, SCA checks our dependencies for known CVEs and bad licences, and a secrets scanner looks for committed keys or tokens.
  7. Quality gate: Test, coverage and scan results are evaluated against the agreed thresholds in one place.
  8. Fail the build (fail): The gate fails, so the pipeline stops here. Nothing is packaged, signed or published.
  9. Package artifact (pass): The gate passes and the build output is packaged as an artifact (JAR, wheel, npm package, binary or image).
  10. SBOM + signing (pass): What exactly did we ship, and can we prove it? An SBOM is generated and the artifact is signed.
  11. Artifact repository (pass): The signed artifact and its SBOM are published to the artifact repository.
  12. Container image scan (pass): Images are scanned again in the registry, so CVEs disclosed after the build are still caught.
StageWhat it answersTool category
RestoreAre dependencies pinned and reachable?Package manager, lockfile, private registry proxy
Lint / formatDoes the code follow the agreed style and avoid obvious bugs?Linters, formatters, type checkers
Compile / bundleDoes it build, reproducibly?Compiler, build tool, bundler
TestDoes it behave correctly, and how much is covered?Test framework, coverage tool
SASTDoes our code contain vulnerable patterns?Static application security testing
SCADo our dependencies have known CVEs or bad licences?Software composition analysis
SecretsDid anyone commit a key or token?Secret scanners
Package / publishWhat exactly did we ship, and can we prove it?Packager, SBOM generator, signer, artifact repository

At a glance: one row per language

LanguageMain build toolPackage managerKey build filesTypical SAST / SCATest frameworkDeep dive
Java / KotlinMaven, GradleMaven Centralpom.xml, build.gradle.ktsSpotBugs + FindSecBugs, OWASP Dependency-CheckJUnit 5Maven Build, Gradle Build
JavaScript / TypeScriptVite, webpack, tscnpm, pnpm, Yarnpackage.json, lockfileESLint security plugins, npm auditJest, Vitestnpm, pnpm and Yarn, JavaScript Bundlers
Pythonbuild, uv, Poetrypip, PyPIpyproject.tomlBandit, pip-auditpytestpip, setuptools and build, uv and Poetry
Gogo buildGo modulesgo.mod, go.sumgosec, govulncheckgo testGo Build
.NETdotnet CLI / MSBuildNuGet*.csproj, *.slnRoslyn analyzers, NuGet auditxUnit, NUnitDotNet Build
C / C++CMake + NinjaConan, vcpkgCMakeLists.txtcppcheck, CoverityGoogleTestCMake, Ninja, Conan and vcpkg, Make and Autotools
RustCargocrates.ioCargo.toml, Cargo.lockClippy, cargo-auditcargo testRust Build with Cargo
RubyRake, BundlerRubyGemsGemfile, Gemfile.lockBrakeman, bundler-auditRSpecBundler and Rake
PHPComposerPackagistcomposer.json, composer.lockPHPStan / Psalm, composer auditPHPUnitComposer
Swift / Kotlin mobilexcodebuild, Gradle (AGP)SwiftPM, MavenPackage.swift, build.gradle.ktsMobSF, SwiftLint, Android LintXCTest, JUnitiOS, Android Gradle Build

Commercial platforms such as Checkmarx, OpenText Fortify, Veracode, Snyk, Black Duck and Mend cover most of these languages; they are listed per language where they are commonly used and compared in Cross-language scanners.

Java and Kotlin (JVM)

Deep dive: Maven Build, Gradle Build

The JVM ecosystem is dominated by Maven (declarative XML, convention over configuration) and Gradle (Groovy or Kotlin DSL, incremental and cached builds). Always commit the wrapper (mvnw, gradlew) so CI uses the same tool version as developers.

  1. Source + pom.xml: A commit triggers CI. pom.xml declares dependencies and plugins, and the committed Maven Wrapper (mvnw) pins the Maven version.
  2. Resolve dependencies: Maven downloads dependencies and plugins from Maven Central or a private Nexus / Artifactory into ~/.m2/repository, which CI caches.
  3. Lint and format: ./mvnw -B checkstyle:check fails on style violations. PMD, Spotless and Error Prone are common additions.
  4. Compile: maven-compiler-plugin:compile runs in the compile phase. Asking for a later phase, such as verify, runs every phase before it.
  5. Test and coverage: maven-surefire-plugin runs the JUnit 5 tests in the test phase, and JaCoCo records coverage (./mvnw -B test jacoco:report).
  6. Security scans in parallel: SpotBugs with FindSecBugs checks our code, OWASP Dependency-Check fails on CVSS 7 or higher, and Gitleaks looks for committed keys and tokens.
  7. Quality gate: ./mvnw -B -ntp verify is the CI target: unit tests, integration tests (Failsafe) and every check bound to verify must pass.
  8. Fail the build (fail): A failing test or check fails the verify phase, so nothing is packaged, signed or deployed.
  9. Package (pass): The package phase writes the .jar (or .war / .ear) to target/.
  10. SBOM and signing (pass): The CycloneDX Maven plugin (makeAggregateBom) writes target/bom.json, and the artifact is signed with Sigstore cosign.
  11. Deploy to the repository (pass): ./mvnw -B deploy uploads to the repository in <distributionManagement>. install is only for local multi-project builds, not CI.
  12. Container image (pass): Jib or Cloud Native Buildpacks build the container image without a Dockerfile, and the registry scans it again.
CategoryCommon tools
Build toolsMaven, Gradle, Ant (+ Ivy), Bazel, sbt (Scala)
Package manager / registryMaven Central, Gradle Plugin Portal, private Artifactory / Nexus
Build filespom.xml, .mvn/maven.config, mvnw, settings.xml, build.gradle / build.gradle.kts, settings.gradle.kts, gradle.properties, gradle/libs.versions.toml, gradlew, gradle/wrapper/gradle-wrapper.properties, build.xml, ivy.xml
Lint and formatCheckstyle, PMD, SpotBugs, Error Prone, Spotless, ktlint and detekt (Kotlin)
SAST (open source)SpotBugs + FindSecBugs, Semgrep, CodeQL, SonarQube Community Build
SAST (commercial)Checkmarx One, OpenText Fortify, Veracode, Coverity, SonarQube Server
SCA / dependency scanningOWASP Dependency-Check, Trivy, Grype, Snyk, Mend, Black Duck, JFrog Xray
FrameworksSpring Boot, Quarkus, Micronaut, Jakarta EE, Ktor (Kotlin)
Test and coverageJUnit 5, TestNG, Mockito, Testcontainers, JaCoCo
Build output.jar, .war, .ear; container images via Jib or Cloud Native Buildpacks
CI cache~/.m2/repository, ~/.gradle/caches, ~/.gradle/wrapper

One example per tool category

1
2
3
4
5
6
7
mvn -B clean verify                              # build (Maven, batch mode)
./gradlew build                                  # build (Gradle wrapper)
mvn checkstyle:check                             # lint
mvn com.github.spotbugs:spotbugs-maven-plugin:check   # SAST (with FindSecBugs plugin configured)
mvn org.owasp:dependency-check-maven:check       # SCA
mvn test jacoco:report                           # test + coverage (JaCoCo plugin configured)
mvn compile jib:dockerBuild                      # container image without a Dockerfile
Minimal pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<project xmlns="http://maven.apache.org/POM/4.0.0">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>demo</artifactId>
  <version>1.0.0</version>
  <packaging>jar</packaging>

  <properties>
    <maven.compiler.release>21</maven.compiler.release>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter</artifactId>
      <version>5.11.4</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>
Minimal build.gradle.kts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
plugins {
    java
}

group = "com.example"
version = "1.0.0"

java {
    toolchain { languageVersion = JavaLanguageVersion.of(21) }
}

repositories { mavenCentral() }

dependencies {
    testImplementation(platform("org.junit:junit-bom:5.11.4"))
    testImplementation("org.junit.jupiter:junit-jupiter")
    testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}

tasks.test { useJUnitPlatform() }

JavaScript and TypeScript

Deep dive: npm, pnpm and Yarn, JavaScript Bundlers

Node.js projects separate the package manager (npm, pnpm, Yarn, Bun) from the build step (TypeScript compiler, bundler). The scripts block in package.json is the contract CI calls. Use npm ci (or pnpm install --frozen-lockfile) in pipelines so the lockfile is enforced.

  1. Source + lockfile: A commit triggers CI. package.json and exactly one committed lockfile (package-lock.json, pnpm-lock.yaml or yarn.lock) define the dependency graph.
  2. Install from the lockfile: npm ci (pnpm install --frozen-lockfile, yarn install --immutable) installs exactly the lockfile and fails if it disagrees with package.json.
  3. Lint and format: npm run lint runs ESLint from a package.json script; Prettier or Biome check formatting.
  4. Build: npm run build runs the project's build script, for example tsc or a bundler.
  5. Test and coverage: npm test runs Jest, Vitest or node --test; add --coverage for Istanbul / c8 coverage.
  6. Security scans in parallel: semgrep scan --config p/nodejs checks our code, npm audit --audit-level=high --omit=dev checks production dependencies, and Gitleaks scans for secrets.
  7. Quality gate: Lint, tests, coverage and the audit are required checks. One failure stops the pipeline before anything is packed.
  8. Fail the build (fail): A failed check stops the pipeline at the gate, so nothing is packaged, signed or published.
  9. Package (pass): npm pack builds the .tgz tarball exactly as the registry would receive it.
  10. SBOM and provenance (pass): npx @cyclonedx/cyclonedx-npm writes sbom.json, and npm publish --provenance adds signed build provenance.
  11. Publish (pass): npm publish --provenance --access public uploads to npmjs.com or a private registry; consumers verify with npm audit signatures.
CategoryCommon tools
Build tools / bundlerstsc, Vite, webpack, esbuild, Rollup, SWC, Turbopack; monorepos: Nx, Turborepo
Package manager / registrynpm, pnpm, Yarn, Bun; npmjs.com registry, private Artifactory / Verdaccio
Build filespackage.json, package-lock.json / pnpm-lock.yaml / yarn.lock / bun.lock, .npmrc, .nvmrc, tsconfig.json, vite.config.ts, webpack.config.js, eslint.config.js, .prettierrc, turbo.json, nx.json
Lint and formatESLint (+ typescript-eslint), Prettier, Biome
SAST (open source)Semgrep, CodeQL, eslint-plugin-security, SonarQube Community Build
SAST (commercial)Checkmarx One, Veracode, Snyk Code, OpenText Fortify, SonarQube Server
SCA / dependency scanningnpm audit, pnpm audit, Retire.js, OSV-Scanner, Trivy, Snyk Open Source, Socket, Mend, Black Duck
FrameworksReact, Angular, Vue, Svelte, Next.js, Nuxt; back end: Express, NestJS, Fastify
Test and coverageJest, Vitest, Mocha, Playwright, Cypress; coverage via Istanbul / c8 / V8
Build outputdist/ bundle, npm package tarball (.tgz), container image
CI cache~/.npm, pnpm store, ~/.cache/yarn, node_modules/.cache

One example per tool category

1
2
3
4
5
6
7
npm ci && npm run build                          # install from lockfile + build
npx eslint . --max-warnings 0                    # lint
npx prettier --check .                           # format check
semgrep scan --config p/javascript --error       # SAST
npm audit --audit-level=high                     # SCA
npx vitest run --coverage                        # test + coverage
npm pack                                         # package as .tgz
Minimal package.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
  "name": "demo",
  "version": "1.0.0",
  "type": "module",
  "engines": { "node": ">=22" },
  "scripts": {
    "build": "tsc -p tsconfig.json",
    "lint": "eslint .",
    "test": "vitest run --coverage"
  },
  "devDependencies": {
    "@vitest/coverage-v8": "^3.0.0",
    "eslint": "^9.0.0",
    "typescript": "^5.6.0",
    "vitest": "^3.0.0"
  }
}

Python

Deep dive: pip, setuptools and build, uv and Poetry

Python packaging has converged on pyproject.toml (PEP 517/518/621): it declares the build backend (setuptools, hatchling, poetry-core, pdm-backend) and project metadata in one file. requirements.txt is still common for applications that are not packaged. uv has become the fast default for resolving, locking and building.

  1. Source + pyproject.toml: A commit triggers CI. pyproject.toml declares the project and build backend, and requirements.txt (compiled by pip-tools) pins versions with hashes.
  2. Install: pip install -r requirements.txt --require-hashes in a fresh venv installs exactly the locked versions; CI caches ~/.cache/pip.
  3. Lint and format: ruff check . && ruff format --check . lint and check formatting; mypy or Pyright add type checking.
  4. Install the project: pip install -e ".[dev]" installs the project and its dev tools, so tests run against the real package metadata.
  5. Test and coverage: pytest --cov=src --cov-fail-under=80 runs the tests and fails if line coverage drops below 80%.
  6. Security scans in parallel: bandit -r src -ll checks our code, pip-audit checks the dependencies against known vulnerabilities, and Gitleaks scans for secrets.
  7. Quality gate: Lint, tests with the 80% coverage gate and both scanners are required checks; one failure stops the pipeline.
  8. Fail the build (fail): A failed check stops the pipeline at the gate, so nothing is packaged, signed or published.
  9. Build the distributions (pass): python -m build creates the wheel (.whl) and sdist (.tar.gz) in dist/, and twine check validates their metadata.
  10. SBOM and signing (pass): cyclonedx-py writes sbom.json from requirements.txt, and the distributions are signed with Sigstore cosign.
  11. Publish (pass): twine upload publishes dist/ to PyPI or a private index (Artifactory, Nexus, devpi).
CategoryCommon tools
Build toolsbuild (PyPA), setuptools, hatchling, Poetry, uv, PDM, Hatch; task runners: tox, nox
Package manager / registrypip, uv, Poetry, Pipenv, conda; PyPI, private Artifactory / devpi
Build filespyproject.toml, requirements.txt, uv.lock, poetry.lock, Pipfile / Pipfile.lock, setup.py / setup.cfg (legacy), MANIFEST.in, tox.ini, noxfile.py, environment.yml, .python-version
Lint and formatRuff, Black, Flake8, Pylint, isort; type checking: mypy, Pyright
SAST (open source)Bandit, Semgrep, CodeQL, SonarQube Community Build
SAST (commercial)Checkmarx One, Veracode, Snyk Code, OpenText Fortify, SonarQube Server
SCA / dependency scanningpip-audit, Safety, OSV-Scanner, Trivy, Snyk Open Source, Mend, Black Duck
FrameworksDjango, Flask, FastAPI; data/ML: pandas, PyTorch
Test and coveragepytest, unittest, Hypothesis; coverage.py / pytest-cov
Build outputwheel (.whl), source distribution (.tar.gz), container image
CI cache~/.cache/pip, ~/.cache/uv, ~/.cache/pypoetry

One example per tool category

1
2
3
4
5
6
7
uv sync --locked && uv build                     # install from lockfile + build wheel/sdist
python -m build                                  # build (PyPA build, any backend)
ruff check . && ruff format --check .            # lint + format
mypy src                                         # type check
bandit -r src -ll                                # SAST (medium severity and above)
pip-audit                                        # SCA
pytest --cov=src --cov-fail-under=80             # test + coverage gate
Minimal pyproject.toml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "demo"
version = "1.0.0"
requires-python = ">=3.11"
dependencies = ["fastapi>=0.115"]

[project.optional-dependencies]
dev = ["pytest", "pytest-cov", "ruff", "bandit", "pip-audit"]

[tool.ruff]
line-length = 100

Go

Deep dive: Go Build

Go ships its build system in the toolchain: go build, go test, go vet and modules need no extra tool. Teams add a Makefile or Taskfile for orchestration and GoReleaser for cross-compiled releases. Set CGO_ENABLED=0 to get static binaries that fit in scratch or distroless images.

  1. Source + go.mod: A commit triggers CI. go.mod lists the module requirements and go.sum records their checksums.
  2. Download and verify modules: go mod download fetches modules through GOPROXY (proxy.golang.org or a private proxy), and go mod verify checks them against go.sum.
  3. Lint and format: gofmt -l must print nothing, then go vet, staticcheck and golangci-lint catch suspicious code.
  4. Compile: CGO_ENABLED=0 go build -trimpath produces a static binary, with the version stamped in through -ldflags.
  5. Test and coverage: go test -race -coverprofile=cover.out ./... runs the tests with the race detector; go tool cover summarises coverage.
  6. Security scans in parallel: gosec checks our code, govulncheck reports only vulnerabilities in code paths we actually call, and Gitleaks scans for secrets.
  7. Quality gate: Formatting, vet, lint, tests and both scanners are required checks; any failure stops the release.
  8. Fail the build (fail): A failed check stops the pipeline at the gate, so nothing is packaged, signed or published.
  9. Cross-compile and package (pass): GoReleaser cross-compiles for each OS and architecture and builds archives and checksums from .goreleaser.yaml.
  10. SBOM and signing (pass): GoReleaser produces SBOMs and signatures from the same config; cyclonedx-gomod is the standalone SBOM tool.
  11. Store the release (pass): Binaries and archives are kept as release assets or in an artifact repository; the CI job stores them with actions/upload-artifact.
  12. Container image (pass): ko builds a minimal container image for the Go binary without a Dockerfile, and the registry scans it again.
CategoryCommon tools
Build toolsgo build, Make, Task, Mage, GoReleaser, Bazel (rules_go), ko (container images)
Package manager / registryGo modules, proxy.golang.org, GOPROXY via Artifactory / Athens
Build filesgo.mod, go.sum, go.work, Makefile, Taskfile.yml, .goreleaser.yaml, .golangci.yml
Lint and formatgofmt, go vet, golangci-lint, staticcheck
SAST (open source)gosec, Semgrep, CodeQL, SonarQube Community Build
SAST (commercial)Checkmarx One, Veracode, Snyk Code, OpenText Fortify, SonarQube Server
SCA / dependency scanninggovulncheck (reachability-aware), OSV-Scanner, Trivy, Grype, Snyk Open Source, Mend
Frameworksnet/http, Gin, Echo, Fiber, chi; gRPC-Go; Cobra (CLIs)
Test and coveragego test (testing), testify, gomock; go test -cover, go tool cover
Build outputSingle static binary; multi-arch archives via GoReleaser; images via ko
CI cache~/go/pkg/mod, ~/.cache/go-build

One example per tool category

1
2
3
4
5
6
CGO_ENABLED=0 go build -trimpath -o bin/app ./cmd/app   # build
golangci-lint run                                # lint (bundles vet, staticcheck, ...)
gosec ./...                                      # SAST
govulncheck ./...                                # SCA (only reports reachable vulnerable code)
go test -race -coverprofile=cover.out ./...      # test + coverage
goreleaser release --snapshot --clean            # package multi-platform release
Minimal go.mod
1
2
3
4
5
module github.com/example/demo

go 1.24

require github.com/gin-gonic/gin v1.10.0

.NET (C#, F#, VB.NET)

Deep dive: DotNet Build

The dotnet CLI wraps MSBuild and NuGet. SDK-style project files are small, and Directory.Build.props / Directory.Packages.props centralise settings and package versions across a solution. Pin the SDK with global.json. Since .NET 8, dotnet restore runs NuGet audit and warns about vulnerable packages. See also DotNet Build.

  1. Source + project files: A commit triggers CI. Project and solution files, Directory.Packages.props and packages.lock.json define the build; global.json pins the SDK.
  2. Restore: dotnet restore --locked-mode restores exactly what packages.lock.json says from NuGet; NuGet audit warns about vulnerable packages.
  3. Lint and format: dotnet format --verify-no-changes fails if the code does not match .editorconfig and the analyzer style rules.
  4. Compile: dotnet build -c Release --no-restore compiles with MSBuild; -warnaserror turns analyzer warnings, including security rules, into errors.
  5. Test and coverage: dotnet test runs xUnit, NUnit or MSTest, and --collect:"XPlat Code Coverage" records coverage with Coverlet.
  6. Security scans in parallel: Roslyn security analyzers check our code, dotnet list package --vulnerable --include-transitive checks dependencies, and Gitleaks scans for secrets.
  7. Quality gate: Format, the build with analyzers as errors, the tests and the vulnerability report must pass before publishing.
  8. Fail the build (fail): A failed check stops the pipeline at the gate, so nothing is packaged, signed or published.
  9. Publish the output (pass): dotnet publish -c Release writes the deployable output; dotnet pack builds a .nupkg for libraries.
  10. SBOM and signing (pass): dotnet CycloneDX writes the SBOM for the solution, and the output is signed with Sigstore cosign.
  11. Publish (pass): Packages go to a NuGet feed (nuget.org, Azure Artifacts, GitHub Packages); deployable output is kept as a CI artifact.
CategoryCommon tools
Build toolsdotnet CLI, MSBuild, Visual Studio Build Tools; build scripting: Cake, NUKE, FAKE (F#)
Package manager / registryNuGet, nuget.org, Azure Artifacts, private Artifactory / ProGet
Build files*.csproj / *.fsproj / *.vbproj, *.sln / *.slnx, Directory.Build.props, Directory.Packages.props, global.json, nuget.config, packages.lock.json, .editorconfig, build.cake
Lint and format.NET (Roslyn) analyzers, StyleCop.Analyzers, dotnet format
SAST (open source)Roslyn security analyzers, Semgrep, CodeQL, SonarQube Community Build
SAST (commercial)Checkmarx One, OpenText Fortify, Veracode, Snyk Code, SonarQube Server
SCA / dependency scanningNuGet audit, dotnet list package --vulnerable, OWASP Dependency-Check, Trivy, Snyk, Mend, Black Duck
FrameworksASP.NET Core, Blazor, .NET MAUI, Entity Framework Core, WPF / WinForms
Test and coveragexUnit, NUnit, MSTest; Coverlet + ReportGenerator
Build output.dll / .exe, dotnet publish folder, NuGet package (.nupkg), container image via dotnet publish /t:PublishContainer
CI cache~/.nuget/packages

One example per tool category

1
2
3
4
5
6
dotnet restore --locked-mode && dotnet build -c Release --no-restore   # build
dotnet format --verify-no-changes                # lint / format
dotnet build -c Release -warnaserror             # analyzers as a gate
dotnet list package --vulnerable --include-transitive   # SCA
dotnet test --collect:"XPlat Code Coverage"      # test + coverage (Coverlet)
dotnet pack -c Release -o out                    # package as .nupkg
Minimal Demo.csproj
1
2
3
4
5
6
7
8
9
10
<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
    <AnalysisLevel>latest-recommended</AnalysisLevel>
    <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
  </PropertyGroup>
</Project>

C and C++

Deep dive: CMake, Ninja, Conan and vcpkg, Make and Autotools

C and C++ have no single standard build tool or package manager. CMake is the de facto meta-build system (it generates Ninja, Make or MSBuild files), with Conan or vcpkg for dependencies. Because dependencies are often vendored or built from source, SCA is harder than in other languages, and commercial snippet-level scanners are common in regulated industries.

  1. Source + CMakeLists.txt: A commit triggers CI. CMakeLists.txt and CMakePresets.json define the build; conanfile.txt or vcpkg.json declare the dependencies.
  2. Dependencies: conan install . --build=missing fetches or builds the dependencies (vcpkg manifest mode is the alternative); conan.lock pins versions.
  3. Configure: cmake --preset release generates the Ninja build files and compile_commands.json for the analyzers.
  4. Build: cmake --build --preset release compiles with Ninja; ccache or sccache avoid recompiling unchanged files.
  5. Test and coverage: ctest runs the GoogleTest or Catch2 tests; a coverage preset plus gcovr --fail-under-line 80 enforces coverage.
  6. Security scans in parallel: clang-tidy and cppcheck check our code, Trivy or Grype scan the Conan / vcpkg manifests (Black Duck adds snippet matching), and Gitleaks scans for secrets.
  7. Quality gate: The build, tests, coverage gate, analyzers and a sanitizer build must pass before packaging.
  8. Fail the build (fail): A failed check stops the pipeline at the gate, so nothing is packaged, signed or published.
  9. Package (pass): cpack builds the release package (.tar.gz, .deb, .rpm or .zip) from the install rules.
  10. SBOM and signing (pass): Syft generates the SBOM from the package, and Sigstore cosign signs it.
  11. Store the package (pass): CI keeps the package with actions/upload-artifact; libraries can also be published to a Conan remote.
CategoryCommon tools
Build toolsCMake, Ninja, Make, Meson, Bazel, MSBuild, Autotools, SCons; compilers: GCC, Clang, MSVC; ccache / sccache
Package manager / registryConan, vcpkg, system packages (apt, dnf), Artifactory (Conan remote)
Build filesCMakeLists.txt, CMakePresets.json, Makefile, meson.build, conanfile.txt / conanfile.py, vcpkg.json, configure.ac / Makefile.am, MODULE.bazel / BUILD.bazel, .clang-format, .clang-tidy
Lint and formatclang-tidy, cppcheck, clang-format, cpplint, include-what-you-use
SAST (open source)cppcheck, Flawfinder, CodeQL, Semgrep; runtime: ASan / UBSan / TSan, fuzzing with libFuzzer / AFL++
SAST (commercial)Coverity, Klocwork, Polyspace, CodeSonar, Parasoft C/C++test, OpenText Fortify, Checkmarx One, SonarQube Server
SCA / dependency scanningBlack Duck (snippet matching), Mend, Snyk (C/C++ unmanaged), Trivy / Grype on Conan or vcpkg manifests
Frameworks / librariesQt, Boost, POCO, gRPC, Abseil
Test and coverageGoogleTest, Catch2, doctest, CTest; gcov / lcov / gcovr, llvm-cov
Build outputExecutables, static (.a / .lib) and shared (.so / .dll / .dylib) libraries, Conan packages
CI cacheccache directory, Conan cache (~/.conan2), vcpkg binary cache

One example per tool category

1
2
3
4
5
6
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release && cmake --build build   # build
clang-tidy -p build src/*.cpp                    # lint (uses compile_commands.json)
cppcheck --enable=warning,performance --error-exitcode=1 src/   # SAST
conan install . --build=missing                  # restore dependencies
ctest --test-dir build --output-on-failure       # test
gcovr -r . --fail-under-line 80                  # coverage gate
Minimal CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
cmake_minimum_required(VERSION 3.25)
project(demo VERSION 1.0.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

add_executable(demo src/main.cpp)

enable_testing()
find_package(GTest REQUIRED)
add_executable(demo_tests tests/demo_test.cpp)
target_link_libraries(demo_tests GTest::gtest_main)
add_test(NAME demo_tests COMMAND demo_tests)

Rust

Deep dive: Rust Build with Cargo

Cargo is build tool, package manager, test runner and documentation generator in one. rustup plus rust-toolchain.toml pins the compiler. Commit Cargo.lock for binaries and build with --locked in CI. See also Rust Build and Deployment Tools Guide.

  1. Source + Cargo.toml: A commit triggers CI. Cargo.toml declares dependencies, Cargo.lock pins them and rust-toolchain.toml pins the compiler.
  2. Fetch crates: Cargo downloads crates from crates.io or a private registry; --locked fails on a stale Cargo.lock, and rust-cache caches ~/.cargo and target/.
  3. Lint and format: cargo fmt --all --check fails on unformatted code, and cargo clippy -- -D warnings turns every lint into an error.
  4. Compile: cargo build --release --locked compiles an optimised native binary.
  5. Test and coverage: cargo nextest run (or cargo test) runs the tests, and cargo llvm-cov --fail-under-lines 80 enforces coverage.
  6. Security scans in parallel: Semgrep checks our code, cargo audit checks the RustSec database, cargo deny checks advisories and licences, and Gitleaks scans for secrets.
  7. Quality gate: Format, Clippy, tests, the coverage gate and the supply-chain checks must pass before release.
  8. Fail the build (fail): A failed check stops the pipeline at the gate, so nothing is packaged, signed or published.
  9. Package the crate (pass): cargo publish --dry-run builds and validates the .crate package; the release binary is the other output.
  10. SBOM and signing (pass): cargo cyclonedx --format json writes the SBOM, and the artifacts are signed with Sigstore cosign.
  11. Publish (pass): cargo publish uploads the crate to crates.io or a private registry; binaries are kept as CI artifacts.
CategoryCommon tools
Build toolsCargo, rustup, cargo-make, cross (cross-compilation), cargo-dist, maturin (Python extensions), Bazel (rules_rust)
Package manager / registryCargo, crates.io, private registries (Artifactory, Cloudsmith)
Build filesCargo.toml, Cargo.lock, rust-toolchain.toml, .cargo/config.toml, build.rs, rustfmt.toml, clippy.toml, deny.toml
Lint and formatrustfmt, Clippy
SAST (open source)Clippy (correctness and suspicious lints), Semgrep, CodeQL, cargo-geiger (unsafe usage)
SAST (commercial)Snyk Code, Checkmarx One, Veracode
SCA / dependency scanningcargo-audit (RustSec), cargo-deny (advisories, licences, bans), OSV-Scanner, Trivy, Snyk Open Source, Mend
FrameworksTokio, Axum, Actix Web, Rocket, Tauri, Leptos
Test and coveragecargo test, cargo-nextest, proptest, criterion (benchmarks); cargo-llvm-cov, cargo-tarpaulin
Build outputNative binary, .rlib, crate package (.crate), Python wheel via maturin
CI cache~/.cargo/registry, ~/.cargo/git, target/ (or sccache)

One example per tool category

1
2
3
4
5
6
cargo build --release --locked                   # build
cargo fmt --check                                # format
cargo clippy --all-targets -- -D warnings        # lint as a gate
cargo audit                                      # SCA (RustSec advisories)
cargo deny check                                 # advisories, licences, banned crates
cargo llvm-cov --fail-under-lines 80             # test + coverage gate
Minimal Cargo.toml
1
2
3
4
5
6
7
8
9
10
11
12
13
[package]
name = "demo"
version = "1.0.0"
edition = "2024"
rust-version = "1.85"

[dependencies]
tokio = { version = "1", features = ["full"] }
axum = "0.8"

[profile.release]
lto = true
codegen-units = 1

Ruby

Deep dive: Bundler and Rake

Bundler resolves and locks gems; Rake is the task runner. New Rails applications ship with Brakeman and RuboCop already wired in, so the security and lint steps usually only need adding to CI.

  1. Source + Gemfile.lock: A commit triggers CI. Gemfile and Gemfile.lock pin every gem, and .ruby-version pins Ruby.
  2. Install: With bundle config set deployment true, bundle install installs exactly Gemfile.lock and fails if it would change.
  3. Lint and format: bundle exec rubocop checks style and common bugs (with rubocop-rails and rubocop-rspec); Standard is a zero-config alternative.
  4. Build assets: For Rails apps, bin/rails assets:precompile builds the production assets; plain gems skip this stage.
  5. Test and coverage: bundle exec rspec runs the specs, with SimpleCov loaded in spec_helper to measure coverage.
  6. Security scans in parallel: Brakeman checks Rails code for vulnerabilities, bundle-audit check --update checks Gemfile.lock against known advisories, and Gitleaks scans for secrets.
  7. Quality gate: RuboCop, the specs and both scanners are required checks; one failure stops the pipeline.
  8. Fail the build (fail): A failed check stops the pipeline at the gate, so nothing is packaged, signed or published.
  9. Build the gem (pass): bundle exec rake build (Bundler's gem tasks) writes pkg/<name>-<version>.gem.
  10. SBOM and signing (pass): Syft generates the SBOM, and Sigstore cosign signs the gem.
  11. Publish (pass): gem push uploads the .gem to RubyGems.org or a private gem server.
CategoryCommon tools
Build toolsRake, Bundler, gem build; version managers: rbenv, rvm, asdf / mise
Package manager / registryBundler, RubyGems.org, private gem server (Artifactory, Gemfury)
Build filesGemfile, Gemfile.lock, *.gemspec, Rakefile, .ruby-version, config.ru, .rubocop.yml
Lint and formatRuboCop, Standard, Reek
SAST (open source)Brakeman (Rails), Semgrep, CodeQL, SonarQube Community Build
SAST (commercial)Checkmarx One, Veracode, Snyk Code, SonarQube Server
SCA / dependency scanningbundler-audit, OSV-Scanner, Trivy, Snyk Open Source, Mend
FrameworksRuby on Rails, Sinatra, Hanami
Test and coverageRSpec, Minitest, Capybara; SimpleCov
Build output.gem package, container image
CI cachevendor/bundle (with BUNDLE_PATH)

One example per tool category

1
2
3
4
5
6
bundle install --jobs 4 && bundle exec rake build   # install + build
bundle exec rubocop                              # lint
bundle exec brakeman --no-pager                  # SAST (Rails)
bundle exec bundle-audit check --update          # SCA
bundle exec rspec                                # test (SimpleCov loaded in spec_helper)
gem build demo.gemspec                           # package as .gem
Minimal Gemfile
1
2
3
4
5
6
7
8
9
10
11
12
13
source "https://rubygems.org"

ruby "3.3.6"

gem "rails", "~> 8.0"

group :development, :test do
  gem "rspec-rails"
  gem "rubocop", require: false
  gem "brakeman", require: false
  gem "bundler-audit", require: false
  gem "simplecov", require: false
end

PHP

Deep dive: Composer

Composer handles dependencies, autoloading and scripts. PHP is interpreted, so “build” usually means installing production dependencies, optimising the autoloader and running static analysis (PHPStan or Psalm), which also does much of the work a compiler does in other languages.

  1. Source + composer.lock: A commit triggers CI. composer.json declares dependencies, composer.lock pins them, and composer validate --strict checks the two agree.
  2. Install: composer install --no-interaction --prefer-dist installs exactly composer.lock from Packagist; CI caches Composer's download cache.
  3. Lint and format: vendor/bin/php-cs-fixer fix --dry-run --diff fails on formatting changes; PHP_CodeSniffer and Laravel Pint are alternatives.
  4. Static analysis: PHP has no compile step, so vendor/bin/phpstan analyse finds type errors and bugs before the tests run.
  5. Test and coverage: vendor/bin/phpunit --coverage-text runs the tests, with coverage from PCOV or Xdebug.
  6. Security scans in parallel: vendor/bin/psalm --taint-analysis traces untrusted input to dangerous sinks, composer audit checks dependencies, and Gitleaks scans for secrets.
  7. Quality gate: Tests, coverage and every scanner are required checks, so a single failure stops the pipeline here.
  8. Fail the build (fail): A failed check stops the pipeline at the gate, so nothing is packaged, signed or published.
  9. Production build (pass): composer install --no-dev --optimize-autoloader --classmap-authoritative builds the production vendor/ tree; Box can package a PHAR.
  10. SBOM and signing (pass): Syft generates the SBOM, and Sigstore cosign signs the release.
  11. Ship (pass): The app and its vendor/ directory ship as a container image to a registry; libraries are published through Packagist instead.
CategoryCommon tools
Build toolsComposer (scripts + autoload), Phing, Box (PHAR packaging)
Package manager / registryComposer, Packagist, private Satis / Private Packagist / Artifactory
Build filescomposer.json, composer.lock, auth.json, phpunit.xml.dist, phpstan.neon, psalm.xml, .php-cs-fixer.dist.php, phpcs.xml
Lint and formatPHP_CodeSniffer, PHP-CS-Fixer, PHPStan, Psalm
SAST (open source)Psalm taint analysis, Semgrep, SonarQube Community Build
SAST (commercial)Checkmarx One, Veracode, Snyk Code, OpenText Fortify, SonarQube Server
SCA / dependency scanningcomposer audit, Roave Security Advisories, OSV-Scanner, Trivy, Snyk Open Source, Mend
FrameworksLaravel, Symfony, Laminas, WordPress, Drupal
Test and coveragePHPUnit, Pest, Codeception; coverage via Xdebug or PCOV
Build outputvendor/ + source deployed as a container image, PHAR archive
CI cacheComposer cache (composer config cache-dir)

One example per tool category

1
2
3
4
5
6
composer install --no-dev --optimize-autoloader --no-interaction   # production build
vendor/bin/php-cs-fixer fix --dry-run --diff     # format check
vendor/bin/phpstan analyse src --level=6         # static analysis
vendor/bin/psalm --taint-analysis                # SAST (taint tracking)
composer audit                                   # SCA
vendor/bin/phpunit --coverage-text               # test + coverage
Minimal composer.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
  "name": "example/demo",
  "type": "project",
  "require": {
    "php": "^8.3",
    "symfony/http-foundation": "^7.1"
  },
  "require-dev": {
    "phpunit/phpunit": "^11.0",
    "phpstan/phpstan": "^2.0"
  },
  "autoload": {
    "psr-4": { "App\\": "src/" }
  },
  "scripts": {
    "test": "phpunit",
    "analyse": "phpstan analyse src"
  }
}

Mobile: Swift (iOS) and Kotlin (Android)

Deep dive: iOS: Xcode and SwiftPM, Android Gradle Build

Mobile builds add code signing, provisioning and store packaging on top of a normal build. iOS builds need macOS runners with Xcode; Android builds run on any OS with the Android SDK and the Android Gradle Plugin (AGP). fastlane is the common automation layer for both.

  1. Source + Package.swift: A commit triggers CI. Package.swift and Package.resolved pin the Swift packages, and the Xcode project or workspace defines the app.
  2. Resolve packages: xcodebuild -resolvePackageDependencies fetches the exact versions in Package.resolved; CI caches SourcePackages and DerivedData.
  3. Lint and format: swiftlint --strict fails on any lint warning; SwiftFormat checks formatting.
  4. Compile: xcodebuild builds the app for the scheme; swift build -c release builds plain Swift packages.
  5. Test and coverage: xcodebuild test runs XCTest and Swift Testing on an iOS Simulator with code coverage on; xcrun xccov reports it.
  6. Security scans in parallel: mobsfscan applies MobSF static rules to our code, OSV-Scanner checks Package.resolved, and Gitleaks scans for secrets.
  7. Quality gate: Tests, coverage and every scanner are required checks, so a single failure stops the pipeline here.
  8. Fail the build (fail): A failed check stops the pipeline at the gate, so nothing is packaged, signed or published.
  9. Archive (pass): xcodebuild archive builds a Release .xcarchive.
  10. Sign and export (pass): Signing needs a distribution certificate and provisioning profile (managed with fastlane match); -exportArchive then writes the .ipa.
  11. Upload to TestFlight (pass): fastlane beta builds and uploads the .ipa to TestFlight through App Store Connect.
  1. Source + build scripts: A commit triggers CI. settings.gradle.kts, the module build.gradle.kts files and libs.versions.toml define the app; gradlew pins Gradle.
  2. Resolve dependencies: Gradle and the Android Gradle Plugin resolve dependencies from Google Maven and Maven Central; setup-gradle caches them.
  3. Lint and format: ./gradlew lint runs Android Lint (including security checks), and ktlintCheck and detekt cover Kotlin style and smells.
  4. Compile: ./gradlew assembleDebug compiles Kotlin and Java, merges resources and builds a debug APK.
  5. Test and coverage: ./gradlew testDebugUnitTest runs the JVM unit tests (including Robolectric), and koverXmlReport records coverage.
  6. Security scans in parallel: mobsfscan and the Android Lint security checks cover our code, ./gradlew dependencyCheckAnalyze checks dependencies, and Gitleaks scans for secrets.
  7. Quality gate: Tests, coverage and every scanner are required checks, so a single failure stops the pipeline here.
  8. Fail the build (fail): A failed check stops the pipeline at the gate, so nothing is packaged, signed or published.
  9. Build the app bundle (pass): ./gradlew bundleRelease builds the release .aab, shrunk by R8; keep mapping.txt to read crash reports.
  10. Sign (pass): The bundle is signed with the upload keystore decoded from CI secrets; Play App Signing re-signs it with the app signing key.
  11. Upload to Google Play (pass): The signed .aab is uploaded to Google Play, which signs and delivers optimised APKs to each device.
CategoryiOS (Swift)Android (Kotlin)
Build toolsXcode / xcodebuild, Swift Package Manager, Tuist, fastlaneGradle + Android Gradle Plugin, fastlane
Package managerSwiftPM, CocoaPods (maintenance mode), CarthageGradle (Maven Central, Google Maven)
Build filesPackage.swift, Package.resolved, *.xcodeproj / *.xcworkspace, *.xcconfig, Info.plist, ExportOptions.plist, Podfile / Podfile.lock, Fastfile, Appfilebuild.gradle.kts, settings.gradle.kts, gradle.properties, gradle/libs.versions.toml, AndroidManifest.xml, proguard-rules.pro, gradlew, Fastfile
Lint and formatSwiftLint, SwiftFormatAndroid Lint, ktlint, detekt
SAST (open source)MobSF, Semgrep, CodeQLMobSF, Semgrep, CodeQL, Android Lint security checks
SAST (commercial)NowSecure, Checkmarx One, Veracode, Snyk Code, SonarQube ServerNowSecure, Guardsquare AppSweep, Checkmarx One, Veracode, Snyk Code
SCASnyk, Mend, OSV-Scanner (Package.resolved)OWASP Dependency-Check, Snyk, Mend, Trivy
FrameworksSwiftUI, UIKit, CombineJetpack Compose, Android Jetpack; cross-platform: Flutter, React Native, Kotlin Multiplatform
Test and coverageXCTest, Swift Testing, XCUITest; Xcode coverage (xccov)JUnit, Espresso, Robolectric; JaCoCo, Kover
Build output.xcarchive, .ipa.apk, .aab (Play Store)
CI cacheSwiftPM .build/, DerivedData, CocoaPods Pods/~/.gradle/caches, ~/.gradle/wrapper

One example per tool category

1
2
3
4
5
6
7
8
9
10
# iOS
swift build -c release                           # build a Swift package
xcodebuild -scheme Demo -configuration Release archive -archivePath build/Demo.xcarchive   # app archive
swiftlint --strict                               # lint
xcodebuild test -scheme Demo -destination 'platform=iOS Simulator,name=iPhone 16' -enableCodeCoverage YES

# Android
./gradlew lint                                   # lint (Android Lint)
./gradlew testDebugUnitTest                      # unit tests
./gradlew bundleRelease                          # signed .aab for the Play Store
Minimal Package.swift
1
2
3
4
5
6
7
8
9
10
11
12
// swift-tools-version: 6.0
import PackageDescription

let package = Package(
    name: "Demo",
    platforms: [.iOS(.v17), .macOS(.v14)],
    products: [.library(name: "Demo", targets: ["Demo"])],
    targets: [
        .target(name: "Demo"),
        .testTarget(name: "DemoTests", dependencies: ["Demo"])
    ]
)

Cross-language scanners

Most organisations run one or two of these across every repository instead of a different scanner per language. Language-specific tools above are still worth keeping because they understand the language more deeply and run fast as pre-commit or PR checks.

ToolTypeLicenceExample
SonarQube (Community Build / Server / Cloud)Code quality + SASTOpen source community build; commercial editionssonar-scanner -Dsonar.projectKey=demo
SemgrepSASTOpen source CE; commercial AppSec Platformsemgrep scan --config auto --error
CodeQLSASTFree for public repos; GitHub Advanced Security for privateGitHub code scanning default setup
TrivySCA, container, IaC, secretsOpen sourcetrivy fs --scanners vuln,secret .
Syft + GrypeSBOM + SCAOpen sourcesyft dir:. -o cyclonedx-json > sbom.json && grype sbom:sbom.json --fail-on high
OSV-ScannerSCAOpen sourceosv-scanner scan source -r .
OWASP Dependency-CheckSCA (strongest for Java and .NET)Open sourcedependency-check --scan . --failOnCVSS 7
Gitleaks / TruffleHogSecretsOpen sourcegitleaks git .
Dependabot / RenovateDependency updatesFree / open sourceConfig in .github/dependabot.yml or renovate.json
SnykSCA, SAST, container, IaCCommercial (free tier)snyk test --severity-threshold=high
Checkmarx OneSAST, SCA, IaCCommercialcx scan create --project-name demo -s .
OpenText FortifySAST, DASTCommercialsourceanalyzer -b demo -scan -f demo.fpr
VeracodeSAST, SCA, DASTCommercialUpload-and-scan or pipeline scan
Black DuckSCA (incl. snippet / licence) and Coverity SASTCommercialdetect.sh (Synopsys/Black Duck Detect)
MendSCA (+ Renovate)CommercialUnified agent / Mend CLI
JFrog XraySCA on stored artifactsCommercialPolicies on Artifactory repositories

More on several of these: DevSecOps, SonarQube, Snyk, Checkmarx and Fortify.

The architect’s view

A DevOps architect rarely picks the build tool (the language community already has). The job is to make many ecosystems behave the same way in the pipeline.

  • Golden pipeline templates. Publish one reusable template per language (GitHub Actions reusable workflows, GitLab CI includes, Azure DevOps templates) with the same stages: restore, lint, build, test, SAST, SCA, package, publish. Teams only override parameters.
  • Pin everything. Commit lockfiles (package-lock.json, poetry.lock, Cargo.lock, packages.lock.json, go.sum), wrappers (mvnw, gradlew) and toolchain files (global.json, rust-toolchain.toml, .nvmrc, .python-version). Builds should fail when the lockfile is out of date (npm ci, --locked, --frozen-lockfile, --locked-mode).
  • One artifact repository as proxy. Route Maven, npm, PyPI, NuGet, Go, Cargo and container pulls through Artifactory or Nexus. It caches, blocks malicious packages and gives SCA a single choke point. See Artifact Management and JFrog Artifactory.
  • Layered scanning. Fast language-native tools on every PR (linters, npm audit, govulncheck, cargo-audit); a central platform (SonarQube, Snyk, Checkmarx, Fortify, Veracode) for governance and reporting; container and SBOM scanning after packaging.
  • Quality gates as policy. Agree on thresholds once: no critical or high CVEs with a fix available, no new SAST findings above medium, coverage on new code at or above a set percentage, no secrets. Enforce them in the template, not in each repository.
  • SBOM and provenance. Generate a CycloneDX or SPDX SBOM for every release (cyclonedx-maven-plugin, @cyclonedx/cyclonedx-npm, cyclonedx-py, cyclonedx-gomod, cargo-cyclonedx, CycloneDX for .NET, or Syft for everything), sign artifacts with Sigstore cosign, and record build provenance to reach the SLSA levels you need.
  • Reproducible, hermetic builds. Prefer containerised build agents with pinned images, cache dependency directories (listed per language above), and avoid network access during the compile step where the toolchain allows it.
LanguageSBOM generatorLockfile to commitToolchain pin
Java / Kotlincyclonedx-maven-plugin, CycloneDX Gradle pluginGradle lockfile (optional)mvnw, gradlew, Gradle toolchains
JavaScript / TypeScript@cyclonedx/cyclonedx-npmpackage-lock.json / pnpm-lock.yaml / yarn.lock.nvmrc, engines, packageManager
Pythoncyclonedx-pyuv.lock / poetry.lock / pinned requirements.txt.python-version
Gocyclonedx-gomodgo.sumgo / toolchain lines in go.mod
.NETCycloneDX for .NETpackages.lock.jsonglobal.json
C / C++Conan / vcpkg SBOM, Syftconan.lock, vcpkg.json baselineToolchain files, container image
Rustcargo-cyclonedxCargo.lockrust-toolchain.toml
Rubycyclonedx-ruby, SyftGemfile.lock.ruby-version
PHPcyclonedx/cyclonedx-php-composercomposer.lockrequire.php in composer.json
Swift / AndroidSyft, CycloneDX Gradle pluginPackage.resolved, Gradle lockfileXcode version on runner, gradlew

Language deep dives in this series:

Other related posts:

This post is licensed under CC BY 4.0 by the author.