Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ root = true
[*.{cs,vb}]
dotnet_analyzer_diagnostic.severity = warning

# License header
dotnet_diagnostic.IDE0073.severity = error
file_header_template = SPDX-License-Identifier: BUSL-1.1

# 1) Unnecessary usings
dotnet_diagnostic.IDE0005.severity = error

Expand Down
30 changes: 4 additions & 26 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
name: CI

on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
branches: [ "**" ]

jobs:
build-and-test:
Expand All @@ -13,21 +11,13 @@ jobs:
- name: Checkout
uses: actions/checkout@v4

- name: Setup .NET (8 LTS and 10 preview)
- name: Setup .NET (8 LTS and 10 GA)
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
8.0.x
10.0.x
dotnet-quality: 'preview'

- name: Cache NuGet packages
uses: actions/cache@v4
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
restore-keys: |
${{ runner.os }}-nuget-
dotnet-quality: 'ga'

- name: Restore
run: dotnet restore src/Coven.sln
Expand All @@ -36,16 +26,4 @@ jobs:
run: dotnet build src/Coven.sln --configuration Release --no-restore

- name: Test
env:
DOTNET_CLI_TELEMETRY_OPTOUT: 1
run: dotnet test src/Coven.sln --configuration Release --no-build --logger "trx;LogFileName=test_results.trx" --collect:"XPlat Code Coverage"

- name: Upload Test Results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results
path: |
**/TestResults/*.trx
**/TestResults/**/coverage.cobertura.xml

run: dotnet test src/Coven.sln --configuration Release --no-build
110 changes: 0 additions & 110 deletions .github/workflows/prerelease-on-pr.yml

This file was deleted.

128 changes: 23 additions & 105 deletions .github/workflows/promote.yml
Original file line number Diff line number Diff line change
@@ -1,130 +1,65 @@
# Promote a stable release
# - Computes a stable semantic version (from input or bump based on build/VERSION).
# - Selects which packages to include (ids -> paths via build/packages.manifest.json).
# - Packs with the exact stable version and creates a GitHub Release (non-prerelease).
# - Optional: publish to NuGet.org if NUGET_API_KEY is provided.

name: promote

on:
workflow_dispatch:
inputs:
version:
description: "Stable version to release (overrides bump)"
required: false
type: string
bump:
description: "Semver bump to compute from build/VERSION"
required: false
required: true
default: patch
type: choice
options: [patch, minor, major]
commit:
description: "Commit SHA or ref to build from"
required: false
type: string
packages:
description: "Comma-separated package IDs to promote (default: all manifest packages)"
required: false
type: string
publish_nuget:
description: "Publish to NuGet.org if NUGET_API_KEY is set"
required: false
type: boolean
default: false

permissions:
contents: write

concurrency:
group: promote-${{ inputs.version || github.ref_name }}
group: promote-${{ github.ref_name }}
cancel-in-progress: false

jobs:
build-pack-release:
runs-on: ubuntu-latest
# Compute booleans once to avoid expression edge-cases with secrets in 'if:'
env:
SHOULD_PUBLISH_NUGET: ${{ inputs.publish_nuget }}
HAS_NUGET_API_KEY: ${{ secrets.NUGET_API_KEY != '' }}

steps:
- name: Checkout (full history + tags)
uses: actions/checkout@v4
with:
ref: ${{ inputs.commit || github.ref }}
fetch-depth: 0
fetch-tags: true

- name: Setup .NET SDK
- name: Setup .NET SDK (10 GA)
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
dotnet-quality: 'preview'
dotnet-quality: 'ga'

- name: Cache NuGet
uses: actions/cache@v4
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
restore-keys: |
${{ runner.os }}-nuget-


- name: Plan release (version and selection)
id: plan
shell: bash
run: |
set -euo pipefail
base=$(tr -d '\r\n' < build/VERSION)

# Compute version
if [[ -n "${{ inputs.version }}" ]]; then
version="${{ inputs.version }}"
else
bump="${{ inputs.bump }}"
IFS='.' read -r MA MI PA <<< "${base%%-*}"
MA=${MA:-0}; MI=${MI:-0}; PA=${PA:-0}
case "$bump" in
major) MA=$((MA+1)); MI=0; PA=0 ;;
minor) MI=$((MI+1)); PA=0 ;;
patch|*) PA=$((PA+1)) ;;
esac
version="$MA.$MI.$PA"
fi
bump="${{ inputs.bump }}"
IFS='.' read -r MA MI PA <<< "${base%%-*}"
MA=${MA:-0}; MI=${MI:-0}; PA=${PA:-0}
case "$bump" in
major) MA=$((MA+1)); MI=0; PA=0 ;;
minor) MI=$((MI+1)); PA=0 ;;
patch|*) PA=$((PA+1)) ;;
esac
version="$MA.$MI.$PA"
echo "version=$version" >> "$GITHUB_OUTPUT"

# Compute selected package paths from manifest
if [[ -n "${{ inputs.packages }}" ]]; then
mapfile -t want < <(echo "${{ inputs.packages }}" | tr ',' '\n' | sed 's/^\s*//; s/\s*$//;' | awk 'NF')
if [[ ${#want[@]} -eq 0 ]]; then
selected_paths=""
else
jq_query='['
for id in "${want[@]}"; do jq_query+=\""${id}\","; done
jq_query=${jq_query%,}
jq_query+=']'
selected_paths=$(jq -r --argjson ids "${jq_query}" \
'.packages | map(select(.id as $i | $ids | index($i))) | .[].path' \
build/packages.manifest.json | paste -sd, -)
fi
else
selected_paths=$(jq -r '.packages[].path' build/packages.manifest.json | paste -sd, -)
fi

if [[ -z "$selected_paths" ]]; then
echo "any=false" >> "$GITHUB_OUTPUT"
echo "paths=" >> "$GITHUB_OUTPUT"
else
echo "any=true" >> "$GITHUB_OUTPUT"
echo "paths=$selected_paths" >> "$GITHUB_OUTPUT"
fi
paths=$(jq -r '.packages[].path' build/packages.manifest.json | paste -sd, -)
echo "paths=$paths" >> "$GITHUB_OUTPUT"

# Determine previous stable version from tags vMAJOR.MINOR.PATCH
prev=$(git tag --list 'v*' | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | sed 's/^v//' | sort -V | tail -n1 || true)
echo "prev=$prev" >> "$GITHUB_OUTPUT"

- name: Validate version monotonicity
if: steps.plan.outputs.any == 'true'
shell: bash
run: |
set -euo pipefail
Expand All @@ -141,14 +76,9 @@ jobs:
exit 1
fi
fi

- name: Build CodeFix (same TFM/Configuration)
run: |
dotnet build src/Coven.Analyzers.CodeFixes/Coven.Analyzers.CodeFixes.csproj \
-c Release -f netstandard2.0


- name: Pack stable
if: steps.plan.outputs.any == 'true'
shell: bash
run: |
set -euo pipefail
Expand All @@ -163,35 +93,23 @@ jobs:

for csproj in "$d"/*.csproj; do
echo "Packing: $csproj"

# Heuristic: treat as analyzer if PackageType=Analyzer OR it already packs to analyzers/*
if grep -qiE '<PackageType>\s*Analyzer\s*</PackageType>|PackagePath="analyzers' "$csproj"; then
echo " Detected analyzer -> no .snupkg; suppress NU5128 warning"
dotnet pack "$csproj" -c Release -o artifacts/nupkg \
/p:Version="$version" \
/p:ContinuousIntegrationBuild=true \
/p:NoWarn=NU5128
else
dotnet pack "$csproj" -c Release -o artifacts/nupkg \
/p:Version="$version" \
/p:ContinuousIntegrationBuild=true \
/p:IncludeSymbols=true \
/p:SymbolPackageFormat=snupkg
fi
dotnet pack "$csproj" -c Release -o artifacts/nupkg \
/p:Version="$version" \
/p:ContinuousIntegrationBuild=true \
/p:IncludeSymbols=true \
/p:SymbolPackageFormat=snupkg
done
done


- name: Upload artifacts
if: steps.plan.outputs.any == 'true'
uses: actions/upload-artifact@v4
with:
name: nupkgs-stable
path: artifacts/nupkg/*
if-no-files-found: error

- name: Create GitHub release
if: steps.plan.outputs.any == 'true'
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ steps.plan.outputs.version }}
Expand All @@ -204,7 +122,7 @@ jobs:
artifacts/nupkg/*.snupkg

- name: Publish to NuGet.org
if: ${{ env.SHOULD_PUBLISH_NUGET == 'true' && env.HAS_NUGET_API_KEY == 'true' }}
if: ${{ secrets.NUGET_API_KEY != '' }}
env:
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
run: |
Expand Down
Loading