diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..394b318 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,16 @@ +# CODEOWNERS — https://docs.github.com/articles/about-code-owners +# +# Scoped to shipped code only, mirroring the Fallout repo's CODEOWNERS. PRs touching +# these paths require a review from a listed owner before merge (enforced via +# `require_code_owner_reviews` on the `main` branch protection rule). +# +# Other paths (build orchestrator, CI workflows, docs, root config) have no code owner +# and are gated only by the required CI status check — the same split Fallout draws, and +# the reason routine build/CI work doesn't need a second pair of eyes to land. + +# The extension itself. +/src/** @Fallout-build/maintainers + +# The Fallout.Vsce plugin — packable and intended for other repos to consume, so it is +# shipped code even though it lives beside the build. +/plugins/** @Fallout-build/maintainers diff --git a/.github/workflows/build-skip.yml b/.github/workflows/build-skip.yml new file mode 100644 index 0000000..40bd755 --- /dev/null +++ b/.github/workflows/build-skip.yml @@ -0,0 +1,38 @@ +# Hand-written (not auto-generated). Companion to build.yml. Ported from the Fallout +# repo's workflow of the same name. +# +# Why this exists: +# - main branch protection requires the `ubuntu-latest` status check (the job name +# emitted by build.yml — branch protection keys on the job, not the workflow +# file/name). +# - build.yml has `paths-ignore: **/*.md`, so it doesn't fire on docs-only PRs. +# - Without a substitute, a docs-only PR sits BLOCKED forever, waiting on a check +# that will never report. +# +# This fires on the exact inverse path set, does nothing of substance, and reports +# success under the same `ubuntu-latest` context — satisfying the rule without paying +# for a real build. +# +# Two things must stay aligned with build.yml, which is generated from +# build/Build.CI.GitHubActions.cs: +# - the job name (`ubuntu-latest`), because that IS the status-check context; +# - the path set, as the exact complement of that file's OnPullRequestExcludePaths. +# A PR touching both a .md and a source file runs both workflows; both report the same +# context and both pass, which is fine. + +name: build + +on: + pull_request: + branches: + - main + paths: + - '**/*.md' + +jobs: + ubuntu-latest: + name: ubuntu-latest + runs-on: ubuntu-latest + steps: + - name: 'Skip: docs-only PR, no build needed' + run: echo "Docs-only change — ubuntu-latest validation skipped via .github/workflows/build-skip.yml." diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 623691c..87157e6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,8 +22,6 @@ on: - main paths-ignore: - '**/*.md' - - '.github/**' - - '!.github/workflows/**' concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/build/Build.CI.GitHubActions.cs b/build/Build.CI.GitHubActions.cs index c534577..e3c5039 100644 --- a/build/Build.CI.GitHubActions.cs +++ b/build/Build.CI.GitHubActions.cs @@ -29,7 +29,10 @@ ConcurrencyCancelInProgress = true, CheckoutRef = "${{ github.head_ref }}", OnPullRequestBranches = [MainBranch], - OnPullRequestExcludePaths = ["**/*.md", ".github/**", "!.github/workflows/**"], + // Kept to a single pattern so build-skip.yml can express the exact inverse. Anything + // more clever here (negations, directory carve-outs) makes the two sets drift, and a + // gap between them means a PR blocked forever on a required check that never fires. + OnPullRequestExcludePaths = ["**/*.md"], InvokedTargets = [nameof(IPackVsix.PackVsix)], PublishArtifacts = false)] partial class Build