feat(fragments): add command with open-changelist append + per-branch impact caps #62
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: .NET | |
| on: | |
| push: | |
| branches: [ "main" ] | |
| pull_request: | |
| branches: [ "main" ] | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| dotnet-version: 10.0.x | |
| - name: Restore dependencies | |
| run: dotnet restore | |
| - name: Build | |
| run: dotnet build --no-restore --nologo | |
| - name: Test with coverage | |
| run: dotnet test --no-build --nologo --collect:"XPlat Code Coverage" --results-directory TestResults | |
| - name: Install gpg (required by codecov-action v5) | |
| run: sudo apt-get install -y gpg | |
| - name: Upload coverage to Codecov | |
| uses: codecov/codecov-action@04b047e8bb82a0c002c8312c1c880fbc6a999d45 # v5 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: TestResults/**/coverage.cobertura.xml | |
| fail_ci_if_error: true | |
| - name: Pack ChangeSharp CLI | |
| run: dotnet pack ChangeSharp.Cli/ChangeSharp.Cli.csproj -o nupkg --nologo | |
| - name: Install ChangeSharp CLI | |
| run: dotnet tool install --global --add-source ./nupkg ChangeSharp.Cli | |
| - name: Validate fragments (PR only — enforce fragments) | |
| if: github.event_name == 'pull_request' | |
| run: changesharp validate --require-fragments | |
| - name: Validate fragments (push to main — no require) | |
| if: github.event_name == 'push' | |
| run: changesharp validate | |
| api-surface: | |
| # Dogfoods the API Surface Gate on ChangeSharp's own public surfaces | |
| # (CLI help, MCP tools, library public API). See docs/features/ApiSurfaceGate.md. | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| dotnet-version: 10.0.x | |
| - name: Regenerate public-surface baselines | |
| run: scripts/update-public-api.sh | |
| - name: Committed baselines must match the regenerated surface | |
| run: | | |
| if ! git diff --exit-code -- tests/public-api/; then | |
| echo "::error::Public-surface baselines are out of date. Run scripts/update-public-api.sh and commit the result." | |
| exit 1 | |
| fi | |
| - name: Derive API impact from the baseline diff vs main | |
| id: surface | |
| run: | | |
| git fetch origin main --depth=1 | |
| DIFF=$(git diff --unified=0 origin/main -- tests/public-api/ || true) | |
| if [ -z "$DIFF" ]; then | |
| LEVEL=patch | |
| else | |
| ADDED=$(echo "$DIFF" | grep -c '^+[^+]' || true) | |
| REMOVED=$(echo "$DIFF" | grep -c '^-[^-]' || true) | |
| if [ "$REMOVED" -gt 0 ]; then LEVEL=major; else LEVEL=minor; fi | |
| fi | |
| echo "Detected API impact level: $LEVEL" | |
| echo "level=$LEVEL" >> "$GITHUB_OUTPUT" | |
| - name: Pack ChangeSharp CLI | |
| run: dotnet pack ChangeSharp.Cli/ChangeSharp.Cli.csproj -o nupkg --nologo | |
| - name: Install ChangeSharp CLI | |
| run: dotnet tool install --global --add-source ./nupkg ChangeSharp.Cli | |
| - name: Enforce fragments against the API surface impact | |
| run: | | |
| export PATH="$PATH:$HOME/.dotnet/tools" | |
| changesharp validate --api-min-level ${{ steps.surface.outputs.level }} | |
| analysis: | |
| # SonarCloud analyzes both main pushes and pull requests. For PRs the scanner | |
| # needs the pull-request parameters plus GITHUB_TOKEN (used to decorate the PR | |
| # with the quality gate). The job-level `if` avoids referencing the secret in a | |
| # step-level `if`, which broke workflow startup before (secrets are not allowed | |
| # in `if:` conditions). | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| steps: | |
| - uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| dotnet-version: 10.0.x | |
| - name: Install SonarScanner for .NET | |
| run: dotnet tool install --global dotnet-sonarscanner --version 11.2.1 | |
| # The generic sonarcloud-github-action cannot analyze C#; only the | |
| # SonarScanner for .NET can. Per Sonar's docs, the coverage report must be | |
| # produced in the same job as the scan (between begin and end), so this job | |
| # builds and tests the solution itself rather than reusing the build job's | |
| # reports (whose relative file paths would not resolve here). | |
| - name: Begin SonarCloud analysis | |
| env: | |
| SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | |
| PR_KEY: ${{ github.event.pull_request.number }} | |
| PR_BRANCH: ${{ github.head_ref }} | |
| PR_BASE: ${{ github.base_ref }} | |
| run: | | |
| pr_args="" | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| pr_args="/d:sonar.pullrequest.key=$PR_KEY /d:sonar.pullrequest.branch=$PR_BRANCH /d:sonar.pullrequest.base=$PR_BASE" | |
| fi | |
| dotnet-sonarscanner begin /k:manuc66_ChangeSharp /o:manuc66-github /d:sonar.token="$SONAR_TOKEN" /d:sonar.host.url=https://sonarcloud.io /d:sonar.cs.cobertura.reportsPaths=TestResults/**/coverage.cobertura.xml /d:sonar.exclusions=**/*Tests*/** $pr_args | |
| - name: Build for SonarCloud analysis | |
| run: dotnet build ChangeSharp.sln -c Release --nologo | |
| - name: Test with coverage | |
| run: dotnet test ChangeSharp.sln -c Release --no-build --nologo --collect:"XPlat Code Coverage" --results-directory TestResults | |
| - name: End SonarCloud analysis | |
| run: dotnet-sonarscanner end /d:sonar.token="$SONAR_TOKEN" | |
| env: | |
| SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |