diff --git a/.changeops/config.json b/.changeops/config.json new file mode 100644 index 00000000..f797fdda --- /dev/null +++ b/.changeops/config.json @@ -0,0 +1,18 @@ +{ + "version": "1.0", + "platform": "github", + "buildSystem": "dotnet", + "release": { + "baseBranch": "main", + "releaseBranchPattern": "releases/v*", + "changesets": { + "enabled": true, + "enforcedOnPR": true, + "bypassLabel": "no-changeset" + } + }, + "github": { + "owner": "kjldev", + "repo": "purview-telemetry-sourcegenerator" + } +} diff --git a/.github/codeql-config.yml b/.github/codeql-config.yml new file mode 100644 index 00000000..0e2e8eab --- /dev/null +++ b/.github/codeql-config.yml @@ -0,0 +1,2 @@ +paths-ignore: + - '**' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e2f4da52..9f11198e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,8 +9,8 @@ on: - main jobs: - format-check: - name: Format Check + lint: + name: lint runs-on: ubuntu-latest steps: @@ -28,13 +28,14 @@ jobs: - name: CSharpier format check run: dotnet csharpier check . - build-and-test: - name: Build and Test + build: + name: build runs-on: ubuntu-latest env: CONFIGURATION: Release - SOLUTION: ./src/Purview.Telemetry.SourceGenerator.slnx + MAIN_SOLUTION: ./src/Purview.Telemetry.SourceGenerator.slnx + SAMPLE_SOLUTION: ./samples/SampleApp/SampleApp.slnx steps: - name: Checkout code @@ -45,22 +46,26 @@ jobs: with: global-json-file: ./src/global.json - - name: Restore dependencies - run: dotnet restore ${{ env.SOLUTION }} + - name: Restore main solution + run: dotnet restore "${MAIN_SOLUTION}" - - name: Build - run: dotnet build ${{ env.SOLUTION }} --no-restore --configuration ${{ env.CONFIGURATION }} + - name: Build main solution + run: dotnet build "${MAIN_SOLUTION}" --no-restore --configuration "${CONFIGURATION}" - - name: Run tests - run: dotnet test ${{ env.SOLUTION }} --no-build --verbosity normal --configuration ${{ env.CONFIGURATION }} + - name: Restore sample solution + run: dotnet restore "${SAMPLE_SOLUTION}" - build-and-test-samples: - name: Build and Test Samples + - name: Build sample solution + run: dotnet build "${SAMPLE_SOLUTION}" --no-restore --configuration "${CONFIGURATION}" + + test: + name: test runs-on: ubuntu-latest env: CONFIGURATION: Release - SOLUTION: ./samples/SampleApp/SampleApp.slnx + MAIN_SOLUTION: ./src/Purview.Telemetry.SourceGenerator.slnx + SAMPLE_SOLUTION: ./samples/SampleApp/SampleApp.slnx steps: - name: Checkout code @@ -69,47 +74,56 @@ jobs: - name: Set up .NET uses: actions/setup-dotnet@v5 with: - global-json-file: ./samples/SampleApp/global.json + global-json-file: ./src/global.json - - name: Restore dependencies - run: dotnet restore ${{ env.SOLUTION }} + - name: Run main solution tests + run: dotnet test "${MAIN_SOLUTION}" --verbosity normal --configuration "${CONFIGURATION}" - - name: Build - run: dotnet build ${{ env.SOLUTION }} --no-restore --configuration ${{ env.CONFIGURATION }} + - name: Run sample solution tests + run: dotnet test "${SAMPLE_SOLUTION}" --verbosity normal --configuration "${CONFIGURATION}" - - name: Run tests - run: dotnet test ${{ env.SOLUTION }} --no-build --verbosity normal --configuration ${{ env.CONFIGURATION }} + doctor: + name: doctor + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v6 + + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version: "24" - changeset-check: - name: Changeset Check - uses: kjldev/.github/.github/workflows/changeset-check.yml@main + - name: Validate ChangeOps config + run: npx -y changeops@1.0.0-prelresase.0 validate ci-gate: name: CI Gate runs-on: ubuntu-latest if: ${{ always() }} needs: - - format-check - - build-and-test - - build-and-test-samples - - changeset-check + - lint + - build + - test + - doctor steps: - name: Verify upstream jobs succeeded env: - FORMAT_CHECK_RESULT: ${{ needs['format-check'].result }} - BUILD_AND_TEST_RESULT: ${{ needs['build-and-test'].result }} - BUILD_AND_TEST_SAMPLES_RESULT: ${{ needs['build-and-test-samples'].result }} - CHANGESET_CHECK_RESULT: ${{ needs['changeset-check'].result }} + LINT_RESULT: ${{ needs['lint'].result }} + BUILD_RESULT: ${{ needs['build'].result }} + TEST_RESULT: ${{ needs['test'].result }} + DOCTOR_RESULT: ${{ needs['doctor'].result }} shell: bash run: | set -euo pipefail declare -A results=( - ["Format Check"]="${FORMAT_CHECK_RESULT}" - ["Build and Test"]="${BUILD_AND_TEST_RESULT}" - ["Build and Test Samples"]="${BUILD_AND_TEST_SAMPLES_RESULT}" - ["Changeset Check"]="${CHANGESET_CHECK_RESULT}" + ["lint"]="${LINT_RESULT}" + ["build"]="${BUILD_RESULT}" + ["test"]="${TEST_RESULT}" + ["doctor"]="${DOCTOR_RESULT}" ) failures=0 diff --git a/.github/workflows/release-validation.yml b/.github/workflows/release-validation.yml new file mode 100644 index 00000000..0ea0db70 --- /dev/null +++ b/.github/workflows/release-validation.yml @@ -0,0 +1,71 @@ +name: Release Validation + +on: + pull_request: + branches: + - main + types: [opened, synchronize, reopened] + +concurrency: + group: release-validation-${{ github.ref }} + cancel-in-progress: true + +jobs: + validate-release-branch: + name: Validate release branch + runs-on: ubuntu-latest + if: startsWith(github.head_ref, 'releases/') + env: + CONFIGURATION: Release + MAIN_SOLUTION: ./src/Purview.Telemetry.SourceGenerator.slnx + SAMPLE_SOLUTION: ./samples/SampleApp/SampleApp.slnx + + steps: + - uses: actions/checkout@v6 + + - uses: actions/setup-node@v4 + with: + node-version: "24" + + - name: ChangeOps validate (packaged CLI) + run: npx -y changeops@1.0.0-prelresase.0 validate + + - uses: actions/setup-dotnet@v5 + with: + global-json-file: ./global.json + + - name: Verify version matches branch + shell: bash + run: | + set -euo pipefail + VERSION="$(node -p "require('./package.json').version")" + EXPECTED="releases/v${VERSION}" + if [[ "${GITHUB_HEAD_REF}" != "${EXPECTED}" ]]; then + echo "::error::Branch '${GITHUB_HEAD_REF}' does not match version '${VERSION}'" + exit 1 + fi + echo "Version/branch alignment OK: ${VERSION}" + + - name: Restore dotnet tools + run: dotnet tool restore + + - name: Format check + run: dotnet csharpier check . + + - name: Restore main solution + run: dotnet restore "${MAIN_SOLUTION}" + + - name: Build main solution + run: dotnet build "${MAIN_SOLUTION}" --no-restore --configuration "${CONFIGURATION}" + + - name: Test main solution + run: dotnet test "${MAIN_SOLUTION}" --no-build --no-restore --verbosity normal --configuration "${CONFIGURATION}" + + - name: Restore sample solution + run: dotnet restore "${SAMPLE_SOLUTION}" + + - name: Build sample solution + run: dotnet build "${SAMPLE_SOLUTION}" --no-restore --configuration "${CONFIGURATION}" + + - name: Test sample solution + run: dotnet test "${SAMPLE_SOLUTION}" --no-build --no-restore --verbosity normal --configuration "${CONFIGURATION}"