CI/CD and Security Scanning
GitHub Actions Workflows
The repository has eight workflows covering build, test, security scanning, and release automation.
.NET Build (.github/workflows/build.yml)
- Purpose: Build and test on every push/PR to
main - Runner:
windows-latest - Steps: Setup .NET 10 →
dotnet restore -p:RestoreLockedMode=true→dotnet build→dotnet test - Tests: 59 unit tests (xUnit + NSubstitute + FluentAssertions)
Release (.github/workflows/release.yml)
- Purpose: Automated dual-architecture release on version tags
- Trigger: Push tag matching
v* - Runner:
windows-latest - Steps:
- Setup .NET 10 →
dotnet test - Optimized publish for win-x64 and win-x86 (R2R, compression, embedded PDB, deterministic, speed-optimized, locked restore)
- Build MSI installers for both architectures via WiX v5
- Create
.7zarchives (LZMA2, max compression) via 7-Zip - Install WinRAR via Chocolatey → create
.rararchives (RAR5 with 5% recovery record) - Generate
checksums.jsonwith SHA256 hashes for all artifacts - Create GitHub Release with all artifacts and auto-generated release notes
- Setup .NET 10 →
- Tool: softprops/action-gh-release
- Naming:
JenkinsAsService_<version>_<arch>.<ext>
CodeQL (.github/workflows/codeql.yml)
- Purpose: Source code vulnerability analysis (C#)
- Tool: github/codeql-action
- Trigger: Push/PR to
main, weekly schedule - Output: Findings in GitHub Security tab
PSScriptAnalyzer (.github/workflows/powershell.yml)
- Purpose: Static analysis of PowerShell code (full ruleset)
- Tool: microsoft/psscriptanalyzer-action
- Output: SARIF uploaded to GitHub Security tab
- Schedule: Sundays at 23:23 UTC
Semgrep (.github/workflows/semgrep.yml)
- Purpose: Pattern-based SAST — vulnerable code patterns, deprecated APIs, common weaknesses
- Tool: semgrep/semgrep-action@v1
- Rules:
p/default+p/csharp+p/secrets(community rulesets, no token required) - Output: SARIF uploaded to GitHub Security tab
- Schedule: Sundays at 04:38 UTC
Gitleaks (.github/workflows/gitleaks.yml)
- Purpose: Secret and credential scanning across full git history
- Tool: gitleaks/gitleaks-action@v3.0.0
- Coverage:
fetch-depth: 0— scans all commits - Schedule: Sundays at 05:00 UTC
Dependency Review (.github/workflows/dependency-review.yml)
- Purpose: Block PRs that introduce NuGet packages with known CVEs
- Trigger: PRs to
main - Tool: actions/dependency-review-action@v5
- Database: GitHub Advisory Database (GHSA)
Trivy — SCA Full Scan (.github/workflows/osv-scanner.yml)
- Purpose: Full-repo dependency vulnerability scan (post-merge + weekly)
- Trigger: Push to
main, weekly schedule (Saturdays 23:28 UTC) - Tool: aquasecurity/trivy-action
- Databases: NVD + GitHub Advisory + OSV
- Output: SARIF uploaded to GitHub Security tab
- Pattern: Calls
trivy-reusable.ymlviauses: ./.github/workflows/trivy-reusable.yml
Trivy — Reusable Workflow (.github/workflows/trivy-reusable.yml)
- Trigger:
workflow_callwith inputsscan-type(default:fs) andscan-ref(default:.) - Steps: checkout → trivy → upload-sarif (
if: always()) - Versioning:
actions/checkout@v6,github/codeql-action/upload-sarif@v4,aquasecurity/trivy-action@v0.36.0
Dependabot (.github/dependabot.yml)
Weekly automated PRs for:
nuget— NuGet package updatesgithub-actions— Action version bumps
Security Scanning Stack Summary
| Layer | Tool | Trigger | Scope |
|---|---|---|---|
| SAST (C#) | CodeQL | Push/PR/weekly | Source code vulnerabilities |
| SAST (patterns) | Semgrep | Push/PR/weekly | Vulnerable patterns, deprecated APIs |
| Secret scanning | Gitleaks | Push/PR/weekly | Secrets/credentials across full git history |
| SAST (PS) | PSScriptAnalyzer | Push/PR/weekly | PowerShell scripts |
| SCA (PR gate) | Dependency Review | PRs only | New CVEs introduced by PR diff |
| SCA (full) | Trivy | Push + weekly | All NuGet deps, multi-DB |
| Dependabot alerts | GitHub native | Always | CVE alerts on current packages |
| Dependabot updates | GitHub native | Weekly PRs | NuGet + GitHub Actions version bumps |
Action Versioning Policy
All actions use floating major-version tags — no SHA pins. Rationale: personal/low-risk repo; SHA pins add friction without meaningful supply-chain benefit at this scale.
| Action family | Tag used |
|---|---|
actions/checkout |
@v6 |
actions/setup-dotnet |
@v5 |
actions/dependency-review-action |
@v5 |
github/codeql-action/* |
@v4 (init/analyze/upload-sarif — all consistent) |
semgrep/semgrep-action |
@v1 |
gitleaks/gitleaks-action |
@v3.0.0 |
microsoft/psscriptanalyzer-action |
SHA pin — repo has no tags (unmaintained since 2023-03-03) |
aquasecurity/trivy-action |
@v0.36.0 |
softprops/action-gh-release |
@v3 |
Note: Removed scanners
- Codacy (
codacy.yml) — removed. The native Codacy GitHub App ("SonarSharp reported by Codacy") is separate. - DevSkim — removed. Docker/MCR rate-limit issues; unmaintained. Replaced by Semgrep + Gitleaks.
Codacy / SonarSharp Alert Resolution (Historical)
PR #13 — 211 alerts to 0
Initial alert storm on first push of feature/secret-protection. Key fixes:
| Category | Fix |
|---|---|
| S1451 — File header | .editorconfig suppression |
| S3990 / ComVisible / CLSCompliant | Added Properties/AssemblyInfo.cs with explicit attributes |
| S2221 — Catch specific exception | Replaced bare catch { } with typed catches |
| S1121 — Cyclomatic complexity | Extracted ParseState + helper methods; CC 12 → 4 |
| S3994 — Uri parameter | Changed BuildJarUri return type to Uri |
PR #14 — 170 alerts to ~147
Two-commit fix sequence addressing S4261 (async suffix), S3994 (Uri params), S134 (nesting depth), S109 (magic numbers), and naming false positives.
Remaining unfixable (~80)
Require Codacy dashboard configuration — not fixable via code:
| Rule | Count | Reason |
|---|---|---|
| S1451 (copyright header) | ~20 | No regex pattern configured on Codacy server |
| S3904/S3991/S3992/S3993 (assembly attributes) | ~58 | Codacy processes each .cs file in isolation |
| S1128/S100/S1515/S4261 | ~7 | False positives on NuGet types and raw string literals |
Warning: Key lesson
// NOSONAR only suppresses line-level rules. File-level rules (S1451, S3904) require Codacy dashboard configuration.
Security Policy (Security.md)
- Scope: JenkinsAsService executable, MSI installer, CI workflows. Jenkins/JDK/OS/third-party packages are out of scope.
- Supported versions: Latest release only. Older versions are not patched.
- Reporting: GitHub Private Vulnerability Reporting (preferred). No public issues for security bugs.
- Response timeline: Acknowledge in 3 business days, assess in 7, patch within 30 days (critical/high) or 90 days (medium/low).
- Coordinated disclosure: 90-day window, reporter can self-disclose after. Credit offered if desired.
- Bounties: None (volunteer project).
Community Files
| File | Purpose |
|---|---|
CONTRIBUTING.md |
Dev setup, PR guidelines, branch naming, commit convention, CI checks |
CODE_OF_CONDUCT.md |
Contributor Covenant v2.0 — enforcement via GitHub private reporting |
Security.md |
Security policy, architecture overview, dependency monitoring |