diff --git a/.github/workflows/build-release-task.yml b/.github/workflows/build-release-task.yml index e68f3aa..54dbf54 100644 --- a/.github/workflows/build-release-task.yml +++ b/.github/workflows/build-release-task.yml @@ -110,15 +110,13 @@ jobs: with: ref: ${{ needs.get-version.outputs.GitCommitId }} - # GeneratePackageOnBuild emits the .nupkg (and .snupkg) from the build, so build, not pack, is the - # one-step producer (dotnet pack on top of it double-packs and fails). OutputPath and PackageOutputPath - # redirect the assembly and the packages out of the .artifacts layout into a build and a publish dir. + # Build the library and its packages into publish/ (both output paths) so they archive together. - name: Build library step run: | set -euo pipefail dotnet build ${{ env.PROJECT_FILE }} \ --configuration ${{ github.ref_name == 'main' && 'Release' || 'Debug' }} \ - -property:OutputPath=${{ runner.temp }}/build/ \ + -property:OutputPath=${{ runner.temp }}/publish/ \ -property:PackageOutputPath=${{ runner.temp }}/publish/ \ -property:Version=${{ needs.get-version.outputs.SemVer2 }} \ -property:FileVersion=${{ needs.get-version.outputs.AssemblyFileVersion }} \ @@ -145,14 +143,22 @@ jobs: --api-key ${{ steps.nuget-login.outputs.NUGET_API_KEY }} \ --skip-duplicate - # Hand the package to the github-release job. Plain name (single target). Consumed within this run, + # Bundle the build output and packages into a flat LanguageTags.7z (cd in so the paths are relative). + - name: Compress release asset step + if: ${{ inputs.publish && !inputs.smoke }} + run: | + set -euo pipefail + cd ${{ runner.temp }}/publish + 7z a -t7z ${{ runner.temp }}/LanguageTags.7z ./* + + # Hand the archive to the github-release job. Plain name (single target). Consumed within this run, # so retention-days: 1 is the failure-path backstop. - name: Upload release asset step if: ${{ inputs.publish && !inputs.smoke }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: release-asset - path: ${{ runner.temp }}/publish/* + path: ${{ runner.temp }}/LanguageTags.7z retention-days: 1 github-release: @@ -190,8 +196,7 @@ jobs: echo "exists=false" >> "$GITHUB_OUTPUT" fi - # target_commitish must be the built commit, or GitHub tags the release on the default branch. The - # release is the tag plus the auto source zip, README, LICENSE, and the .nupkg/.snupkg. + # target_commitish must be the built commit, or GitHub tags the release on the default branch. - name: Create GitHub release step if: ${{ steps.release-exists.outputs.exists == 'false' || github.event_name == 'workflow_dispatch' }} uses: softprops/action-gh-release@718ea10b132b3b2eba29c1007bb80653f286566b # v3.0.1 @@ -204,7 +209,7 @@ jobs: files: | LICENSE README.md - ${{ runner.temp }}/publish/* + ${{ runner.temp }}/publish/LanguageTags.7z # Reclaim the transfer artifact now the release holds durable copies. Same gate as the create step # (exists == false || dispatch), so a no-op re-run keeps its artifact for the retention backstop. diff --git a/.github/workflows/merge-bot-pull-request.yml b/.github/workflows/merge-bot-pull-request.yml index a9d5420..1ec57af 100644 --- a/.github/workflows/merge-bot-pull-request.yml +++ b/.github/workflows/merge-bot-pull-request.yml @@ -53,7 +53,7 @@ jobs: main) method=--merge ;; *) echo "::error::Unsupported base branch: ${{ github.event.pull_request.base.ref }}"; exit 1 ;; esac - gh pr merge --auto "$method" "$PR_URL" + gh pr merge --auto --delete-branch "$method" "$PR_URL" env: PR_URL: ${{ github.event.pull_request.html_url }} GH_TOKEN: ${{ steps.app-token.outputs.token }} @@ -92,7 +92,7 @@ jobs: main) method=--merge ;; *) echo "::error::Unsupported base branch: ${{ github.event.pull_request.base.ref }}"; exit 1 ;; esac - gh pr merge --auto "$method" "$PR_URL" + gh pr merge --auto --delete-branch "$method" "$PR_URL" env: PR_URL: ${{ github.event.pull_request.html_url }} GH_TOKEN: ${{ steps.app-token.outputs.token }} diff --git a/WORKFLOW.md b/WORKFLOW.md index 698f5cd..520a65c 100644 --- a/WORKFLOW.md +++ b/WORKFLOW.md @@ -212,9 +212,11 @@ release by dispatch. A merged dependency bump does not itself publish. See D8. The repo produces exactly one shipped artifact, the NuGet package. The leaf pushes the package, and where symbols are enabled its symbol package, to NuGet.org via OIDC trusted publishing (no long-lived API key, -D4.7), and attaches the `.nupkg`/`.snupkg` to the GitHub release. There is no generic multi-target -abstraction: no `enable_` flag selecting among leaves, no `expect_release_assets` toggle, no -`release-asset--*` glob. The single asset is attached directly by plain name. +D4.7), and bundles them with the compiled library into a single fixed-name `LanguageTags.7z` attached to +the GitHub release. There is no generic multi-target abstraction: no `enable_` flag selecting among +leaves, no `expect_release_assets` toggle, no `release-asset--*` glob. The single asset, +`LanguageTags.7z`, is attached by its fixed name, so `releases/latest/download/LanguageTags.7z` is a stable +download URL. ## 4. Behavioral contract - expected outcomes @@ -301,8 +303,9 @@ applicable guarantee is not operational (section 1). `GitCommitId`), never `github.sha` of a moving ref. *Prevents: the tag landing on a different commit than was built.* - **D4.4 Release contents and flag.** Output: every release is a tag on the built commit plus the auto - source zip, README, and LICENSE, with the `.nupkg` and (where `IncludeSymbols`) the `.snupkg` attached. - The GitHub-release `prerelease` boolean is set to `github.ref_name != 'main'`. *(GitHub computes the + source zip, README, and LICENSE, with a fixed-name `LanguageTags.7z` attached that bundles the compiled + library, the `.nupkg`, and (where `IncludeSymbols`) the `.snupkg`. The GitHub-release `prerelease` + boolean is set to `github.ref_name != 'main'`. *(GitHub computes the "Latest" badge from semver across non-prerelease releases, a consequence, not a workflow assertion.)* - **D4.5 No-op republish.** Input: a re-run whose version is unchanged. Output: the release-create step is skipped when the tag already exists (refreshed only on `workflow_dispatch`). The NuGet push runs and @@ -437,8 +440,9 @@ guarantee, each pass/fail/N-A with a `file:line` citation: `PUBLISH_ON_MERGE`; the dispatch path is guarded to `main`/`develop`; the publisher calls the same `validate-task` as a `validate` job and the publish job `needs:` it (D4.6); the run publishes only `github.ref_name`; `target_commitish` is the NBGV commit id; the GitHub-release `prerelease` boolean - `== (github.ref_name != 'main')`; the release body attaches the source zip, README, and LICENSE; the - leaf pushes `*.nupkg` and `*.snupkg` (symbols enabled) with `--skip-duplicate`; the publish job grants + `== (github.ref_name != 'main')`; the release body attaches the source zip, README, LICENSE, and a + fixed-name `LanguageTags.7z` bundle (compiled library + `.nupkg`/`.snupkg`); the leaf pushes `*.nupkg` + and `*.snupkg` (symbols enabled) with `--skip-duplicate`; the publish job grants `id-token: write` and pushes with a `NuGet/login@v1` short-lived key, not a `NUGET_API_KEY` secret (D4.7); release-create gated `exists == false || workflow_dispatch`. - **D5:** each cross-job transfer artifact has a delete gated to its consumer, `continue-on-error: true`, diff --git a/repo-config/README.md b/repo-config/README.md index 2489845..70af52e 100644 --- a/repo-config/README.md +++ b/repo-config/README.md @@ -21,7 +21,8 @@ templates); repository administration config-as-code is the maintainer's, so it - [`ruleset-main.json`](./ruleset-main.json) - the `main` branch ruleset (merge-commit-only, signed commits, the same required check, strict **off**; no linear-history rule). - [`settings.json`](./settings.json) - repository settings (auto-merge on; squash **and** merge-commit - allowed; rebase off; delete branch on merge). + allowed; rebase off; auto-delete-on-merge **off**, so `main`/`develop` survive a promotion - the + merge-bot passes `--delete-branch` for bot PRs, and feature PRs are merged with `--delete-branch`). ## What it does not store diff --git a/repo-config/settings.json b/repo-config/settings.json index 7c5d338..fc373ef 100644 --- a/repo-config/settings.json +++ b/repo-config/settings.json @@ -3,5 +3,5 @@ "allow_merge_commit": true, "allow_rebase_merge": false, "allow_auto_merge": true, - "delete_branch_on_merge": true + "delete_branch_on_merge": false }