Skip to content

Optimize CI: lightweight lint on push, full build on PR only, conditional CodeQL #81

Description

@mcpolo99

Problem

Every push to a feature branch triggers full MSBuild build + test + coverage (~9 min of Windows runner time). This burns GitHub Actions minutes on work that will be validated again when a PR is opened. CodeQL also runs on every master push/PR unnecessarily.

Goal

Minimize CI minutes on routine development work while maintaining full validation before merge.

Proposed Workflow Layout

Workflow Trigger What it does Time
lint.yml (new) Push to any branch + PRs Format + style + Roslyn analyzers (no build) ~2 min
ci.yml PRs + push to master/pre-release Full build + package + release ~4-5 min
test.yml PRs only Full build + test + coverage + PR comment ~5 min
codeql Weekly (if changes) + manual Security analysis ~14 min
format.yml Delete Replaced by lint.yml -

Cost Comparison

Event Before After
Push to feature branch ~9 min (full build + test) ~2 min (lint only)
PR opened/updated ~11 min ~11 min (same, this is where it matters)
PR merged to pre-release ~10 min ~5 min (ci only, no test re-run)
PR merged to master ~24 min (ci + test + codeql) ~5 min (ci only)
Weekly (if changes) - ~14 min (codeql, conditional)

Estimated monthly savings: 50-70% reduction in Windows runner minutes.

Implementation Details

1. lint.yml — Lightweight source checks (no build)

Uses dotnet format subcommands which run Roslyn analyzers in-memory without producing binaries:

dotnet restore                              # cached, ~10s
dotnet format whitespace --verify-no-changes  # indentation, line endings
dotnet format style --verify-no-changes       # IDE* rules (naming, var usage)
dotnet format analyzers --verify-no-changes   # CA* + RCS* rules

Results posted to:

  • PR comment (if triggered by PR)
  • Issue comment (if branch name matches {number}-{slug} pattern from gh issue develop)
  • Job summary (always, visible in Actions tab)

2. ci.yml — Remove feature branch push trigger

Change from:

on:
  push:
    branches: [master, pre-release, feature/**, fix/**]

To:

on:
  push:
    branches: [master, pre-release]
  pull_request:
    branches: [master, pre-release]

Feature/fix branch pushes no longer trigger a full build.

3. test.yml — PR only

Change from push + PR triggers to PR only. Tests already ran during PR — no need to re-run on merge push.

4. CodeQL — Weekly conditional + manual

on:
  schedule:
    - cron: "0 3 * * 1"   # Every Monday 3am
  workflow_dispatch:        # Manual trigger from Actions tab

steps:
  - name: Check for recent commits
    run: |
      # Skip if no commits in last 7 days
      count=$(git log --oneline --since="7 days ago" | wc -l)
      if [ "$count" -eq 0 ]; then echo "skip=true"; fi

Removes push/PR triggers entirely. Only runs weekly on master if there were actual changes, or manually when needed.

5. Delete format.yml

Replaced by lint.yml which covers formatting + style + analyzers in one workflow.

6. Developer workflow update (CONTRIBUTING.md)

Document the recommended flow using GitHub's built-in branch creation:

gh issue develop 54 --checkout           # creates branch 54-nuget-packages
# ... work, commit, push ...
# → lint runs in ~2 min, posts results to issue #54
gh pr create --fill                      # opens PR, full CI kicks in

Branch naming follows GitHub convention: {issue-number}-{slugified-title}. The lint workflow parses the issue number from the branch name to post comments on the linked issue.

Reasoning

  • Feature branch pushes are exploratory — developers push frequently, full CI is wasted
  • PRs are the quality gate — that's where full validation matters
  • Roslyn analyzers catch real issues — naming, complexity, code quality — without building
  • CodeQL is expensive and slow — weekly is sufficient for a project this size
  • GitHub's branch naming is battle-tested — no custom scripts needed, auto-sanitized
  • Issue comments from lint give developers feedback without opening a PR first

Related

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions