mirror of
https://github.com/OPCFoundation/UA-.NETStandard.git
synced 2026-10-26 04:19:53 +08:00
## Description Two related changes to how the 2.0 line is built and shipped. ### 1. Release-branch-only package publication - `master` produces development previews only. - Stable packages can only be built from a canonical `release/<major>.<minor>` branch and are promoted manually from the exact signed candidate artifact. - Core packages use explicit `major.minor.patch` versions (`2.0.0`, `2.0.1`, then `2.1.0`); git height never changes a stable package patch. - XRegistry, WoT Connectivity, Vision, Robotics, Redundancy, Positioning, OpenUSD, ISA95, AI, DI, the relevant MCP extensions, and OpenUSD connector tools remain `-preview.N` while following the core numeric version. - nuget.org receives only non-`.Debug` package IDs; GitHub Packages retains the complete signed Release/Debug candidate. - `docs/ReleaseProcess.md` is a reproducible runbook for developers and agents, with each step stating its completion evidence. Promotion is source-bound and byte-checked: `release.yml` checks out nothing until the candidate SHA is known, and `assert-published-packages-match.ps1` proves that any version already on a feed holds *this* candidate's content before `--skip-duplicate` is allowed to skip it. Canonical release-branch naming is matched case-sensitively with no leading zeroes, and `version.json`'s `publicReleaseRefSpec`, both policy helpers and the copy `release.yml` inlines are pinned to one expression by tests. ### 2. PR CI moved to GitHub-hosted runners - `.github/workflows/buildandtest.yml` (**CI**) now owns pull-request validation outright, covering the Windows Debug/Release net48 + net10.0 solution builds and fast tests that only Azure Pipelines ran, alongside the existing Linux/macOS, all-target and NativeAOT legs. `build-and-test summary` remains the stable required check name. - `.github/workflows/nightly.yml` is a new **manual-only** (`workflow_dispatch`) full-scope workflow covering the Azure nightly workload: all solutions x seven target profiles x Debug/Release, the net472/netstandard profiles, Windows + Linux NativeAOT, and the long-running and durable tiers. - Shared deterministic discovery/batching lives in `.github/scripts/get-ci-matrix.ps1` with a local composite action, so both entry points expand the same workload manifest instead of duplicating a large embedded script. - `azure-pipelines.yml` is set to `pr: none`. - The standalone pump sample image workflow is folded into the consolidated **Images CI** workflow, which now builds all ten images and publishes an `images summary` rollup suitable as a required check. ## Related Issues No related issue provided. ## Checklist - [ ] I have signed the [CLA](https://opcfoundation.org/license/cla/ContributorLicenseAgreementv1.0.pdf) and read the [CONTRIBUTING](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/CONTRIBUTING.md) doc. - [x] I have added tests that prove my fix is effective or that my feature works and increased code coverage. - [x] I have added all necessary documentation. - [x] I have verified that my changes do not introduce (new) build or analyzer warnings. - [ ] I ran **all** tests locally using the **UA.slnx** solution against at least .net **framework** and .net **10**, and all passed. - [ ] I fixed **all** failing and flaky tests in the CI pipelines and **all** CodeQL warnings. - [x] I have addressed **all** PR feedback received. ## Validation - `Opc.Ua.Tools.Tests` full `net10.0` suite: **959 passed, 1 skipped, 0 failed**. - Version/package-policy regression subset (`PackageVersionPolicyTests`): **60 passed, 0 failed**. - GitHub Actions **CI** run 35719807620: **149/149 jobs green** on GitHub-hosted runners. - Canonical release-branch rule verified against the pinned nbgv 3.7.115 by building throwaway branches: `release/2.0`, `release/0.9`, `release/10.42` -> `PublicRelease=True`; `release/02.0`, `release/2.00`, `Release/2.0` -> `False`. - Package identity gate verified against a live nuget.org package: served packages carry a repository `.signature.p7s`, so equality is decided on content excluding that part. Re-signing and zip reordering produce an identical digest; a one-byte content change does not. - Synthetic Release-only, Debug-only, combined, preview, duplicate, orphaned-symbol, mismatched-root and accidental-stable-family package sets exercise the shared validator. - Stable-release rehearsal in an isolated `release/2.0` clone: `Opc.Ua.Di` packed as `2.0.0-preview.6` depending on stable Core `2.0.0`; `Opc.Ua.Di.Client` likewise against stable Client `2.0.0`. - All workflow YAML, `version.json`, the package-policy PowerShell scripts and the internal release-runbook anchors parse. ## Known validation limits - Full `UA.slnx` `net48` and `net10.0` local validation remains blocked by pre-existing `NETSDK1005` and dependency-version failures in unmodified fuzz/sample projects; the corresponding checklist items intentionally stay open. - The TRX-driven test verdict added for the intermittent at-exit host stall is proven by `CiTestVerdictTests`; the stall itself has not recurred since. - `nightly.yml` has not yet been run against a full-scope Azure run for tuple-level parity — see below. ## Operational follow-up This remains a preparation PR targeting `master`. It does **not** authorize a release. Release sequence: 1. Merge this PR. 2. Create canonical `release/2.0`, advance `master` to `2.1.0-preview.{height}`, and open a separate `2.0.0` version PR against `release/2.0`. 3. Follow [`docs/ReleaseProcess.md`](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/ReleaseProcess.md) for candidate dry-run, environment approval, promotion, tag/release finalization, and next-patch preview setup. CI migration steps still needing administrator access are tracked in [`docs/DeveloperGuide.md#migration-status`](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/docs/DeveloperGuide.md#migration-status): proving `nightly.yml` parity on a trusted SHA with the private fuzz corpus provisioned, turning off definition 14's service-side PR override, retiring the Azure full-scope schedules and push trigger, and retiring the duplicate `azure-pipelines-preview.yml` publisher. > **Before cutting `release/2.0`:** the `Release` ruleset requires the Azure context for *every* `refs/heads/release/*`, but a new 2.x branch inherits `pr: none`, so that context would never report and would block every PR into the new line. Exclude the new ref from that ruleset, or add a 2.x ruleset requiring `build-and-test summary`, as part of creating the branch. --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
407 lines
18 KiB
YAML
407 lines
18 KiB
YAML
name: Release to nuget.org
|
|
|
|
# Manual promotion of the exact signed package bytes produced by a successful
|
|
# nuget-publish.yml run on a canonical "release/<major>.<minor>" branch (e.g.
|
|
# release/2.0). The release environment provides the approval boundary (its
|
|
# deployment_branch_policy restricts execution to release/* branches) and the
|
|
# NuGet trusted publishing identity. This workflow additionally requires the
|
|
# candidate's base package version to be an exact stable release (no
|
|
# prerelease label or build metadata, e.g. "2.0.0") - a preview candidate is
|
|
# already published automatically by nuget-publish.yml and must never be
|
|
# promoted here. See docs/ReleaseProcess.md ("Approved promotion") for the
|
|
# full procedure, including how to pick a release_run_id and how to recover
|
|
# from a partial or failed promotion.
|
|
#
|
|
# One-time nuget.org trusted publishing policy:
|
|
# Repository Owner: OPCFoundation
|
|
# Repository: UA-.NETStandard
|
|
# Workflow File: release.yml
|
|
# Environment: release
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
release_run_id:
|
|
description: Successful nuget-publish.yml run ID from a release/<major>.<minor> branch
|
|
required: true
|
|
type: string
|
|
dry_run:
|
|
description: Validate the selected package set without publishing
|
|
required: false
|
|
type: boolean
|
|
default: false
|
|
|
|
permissions:
|
|
actions: read
|
|
contents: read
|
|
id-token: write
|
|
packages: write
|
|
|
|
concurrency:
|
|
group: nuget-release
|
|
cancel-in-progress: false
|
|
|
|
jobs:
|
|
publish:
|
|
name: Promote signed packages
|
|
runs-on: windows-2025
|
|
environment: release
|
|
|
|
steps:
|
|
# Deliberately no checkout here. This job holds the release environment
|
|
# plus packages:write and id-token:write, so no repository code may run
|
|
# before the workspace is bound to the candidate's own commit - the
|
|
# branch tip could otherwise have been changed after the candidate was
|
|
# built and would execute with those credentials. The step below
|
|
# therefore uses only the GitHub API and an inline branch-shape check,
|
|
# and the first and only checkout is at the candidate SHA.
|
|
- name: Setup .NET 10.0
|
|
uses: actions/setup-dotnet@v6
|
|
with:
|
|
dotnet-version: '10.0.401'
|
|
|
|
- name: Validate selected publish run
|
|
id: source
|
|
shell: pwsh
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
RELEASE_RUN_ID: ${{ inputs.release_run_id }}
|
|
run: |
|
|
if ($env:RELEASE_RUN_ID -notmatch '^\d+$') {
|
|
throw 'release_run_id must be a numeric GitHub Actions run ID.'
|
|
}
|
|
|
|
$runJson = gh api "repos/$($env:GITHUB_REPOSITORY)/actions/runs/$env:RELEASE_RUN_ID"
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "Unable to read workflow run $env:RELEASE_RUN_ID."
|
|
}
|
|
$run = $runJson | ConvertFrom-Json
|
|
|
|
$workflowJson = gh api (
|
|
"repos/$($env:GITHUB_REPOSITORY)/actions/workflows/$($run.workflow_id)")
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "Unable to identify the workflow for run $env:RELEASE_RUN_ID."
|
|
}
|
|
$workflow = $workflowJson | ConvertFrom-Json
|
|
|
|
if ($workflow.path -cne '.github/workflows/nuget-publish.yml') {
|
|
throw "Run $env:RELEASE_RUN_ID belongs to '$($workflow.path)', not nuget-publish.yml."
|
|
}
|
|
if ($run.status -cne 'completed' -or $run.conclusion -cne 'success') {
|
|
throw (
|
|
"Run $env:RELEASE_RUN_ID is not successful: " +
|
|
"status=$($run.status), conclusion=$($run.conclusion).")
|
|
}
|
|
if (-not $run.head_branch.StartsWith(
|
|
'release/',
|
|
[StringComparison]::OrdinalIgnoreCase)) {
|
|
throw (
|
|
"Run $env:RELEASE_RUN_ID came from '$($run.head_branch)'. " +
|
|
'Only release/* branches can be promoted.')
|
|
}
|
|
# Inlined on purpose rather than dot-sourced from
|
|
# .azurepipelines/package-version-policy.ps1: nothing from the
|
|
# repository may execute before the candidate checkout below. This
|
|
# is the same shape as Test-CanonicalReleaseBranchRef, and
|
|
# PackageVersionPolicyTests pins the two together so they cannot
|
|
# drift apart.
|
|
if ("refs/heads/$($run.head_branch)" -notmatch '(?-i)^refs/heads/release/(0|[1-9]\d*)\.(0|[1-9]\d*)$') {
|
|
throw (
|
|
"Run $env:RELEASE_RUN_ID came from '$($run.head_branch)', which is not a " +
|
|
"canonical release/<major>.<minor> branch (for example release/2.0). Only " +
|
|
'that naming may be promoted; see docs/ReleaseProcess.md.')
|
|
}
|
|
if ($env:GITHUB_REF -cne "refs/heads/$($run.head_branch)") {
|
|
throw (
|
|
"This release.yml dispatch runs from '$($env:GITHUB_REF)', but the selected " +
|
|
"candidate was built from 'refs/heads/$($run.head_branch)'. Dispatch " +
|
|
'release.yml from that exact canonical release branch so the validation ' +
|
|
'policy and promotion code are source-bound to the candidate.')
|
|
}
|
|
if ($run.head_repository.full_name -cne $env:GITHUB_REPOSITORY) {
|
|
throw (
|
|
"Run $env:RELEASE_RUN_ID came from '$($run.head_repository.full_name)', " +
|
|
"not '$($env:GITHUB_REPOSITORY)'.")
|
|
}
|
|
|
|
"commit=$($run.head_sha)" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
|
|
"branch=$($run.head_branch)" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
|
|
"artifact=opcua-packages-$env:RELEASE_RUN_ID" |
|
|
Out-File -FilePath $env:GITHUB_OUTPUT -Append
|
|
Write-Host (
|
|
"Selected successful nuget-publish.yml run $env:RELEASE_RUN_ID " +
|
|
"for $($run.head_branch) at $($run.head_sha).")
|
|
|
|
- name: Check out the candidate commit
|
|
# First and only checkout, and deliberately after the validation step
|
|
# above: the dispatch ref pins a branch, not a commit, so checking out
|
|
# the branch tip would let a commit that landed after the candidate was
|
|
# built supply the promotion logic. Binding to the candidate's own SHA
|
|
# makes the validator, the policy scripts and the package bytes all
|
|
# describe the same source.
|
|
uses: actions/checkout@v6
|
|
with:
|
|
ref: ${{ steps.source.outputs.commit }}
|
|
|
|
- name: Download signed promotion artifact
|
|
uses: actions/download-artifact@v8
|
|
with:
|
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
run-id: ${{ inputs.release_run_id }}
|
|
name: ${{ steps.source.outputs.artifact }}
|
|
path: promotion
|
|
|
|
- name: Validate promotion manifest and package bytes
|
|
shell: pwsh
|
|
env:
|
|
RELEASE_RUN_ID: ${{ inputs.release_run_id }}
|
|
RELEASE_BRANCH: ${{ steps.source.outputs.branch }}
|
|
RELEASE_COMMIT: ${{ steps.source.outputs.commit }}
|
|
run: |
|
|
. ./.azurepipelines/package-version-policy.ps1
|
|
$manifestPath = 'promotion/release-manifest.json'
|
|
if (-not (Test-Path -LiteralPath $manifestPath)) {
|
|
throw "The selected run artifact contains no release-manifest.json."
|
|
}
|
|
$manifest = Get-Content -LiteralPath $manifestPath -Raw | ConvertFrom-Json
|
|
$expectedRef = "refs/heads/$($env:RELEASE_BRANCH)"
|
|
if (($manifest.schemaVersion -ne 1 -and $manifest.schemaVersion -ne 2) -or
|
|
$manifest.repository -cne $env:GITHUB_REPOSITORY -or
|
|
$manifest.workflow -cne '.github/workflows/nuget-publish.yml' -or
|
|
$manifest.runId -cne $env:RELEASE_RUN_ID -or
|
|
$manifest.ref -cne $expectedRef -or
|
|
$manifest.commit -cne $env:RELEASE_COMMIT) {
|
|
throw (
|
|
"The promotion manifest does not match nuget-publish.yml run " +
|
|
"$($env:RELEASE_RUN_ID) on $expectedRef.")
|
|
}
|
|
$expectedBaseVersion = if ($manifest.schemaVersion -eq 2) {
|
|
$manifest.basePackageVersion
|
|
}
|
|
else {
|
|
$manifest.packageVersion
|
|
}
|
|
|
|
# This workflow exists solely to promote a stable release (e.g.
|
|
# "2.0.0", "2.0.1", "2.1.0") to nuget.org. In-development preview
|
|
# candidates are already published automatically by
|
|
# nuget-publish.yml and must never be promoted here. See
|
|
# docs/ReleaseProcess.md ("Approved promotion").
|
|
if (-not (Test-StablePackageVersion -Version $expectedBaseVersion)) {
|
|
throw (
|
|
"Run $($env:RELEASE_RUN_ID) produced base version " +
|
|
"'$expectedBaseVersion', which is not an exact stable release. Only a " +
|
|
'stable candidate (no prerelease label or build metadata) may be ' +
|
|
'promoted through this workflow.')
|
|
}
|
|
if (-not (Test-CanonicalReleaseBranchForPackageVersion `
|
|
-Ref $expectedRef `
|
|
-Version $expectedBaseVersion)) {
|
|
throw (
|
|
"Candidate version '$expectedBaseVersion' does not match release branch " +
|
|
"'$expectedRef'. A stable M.m.p candidate must be promoted only from " +
|
|
'the matching release/M.m branch.')
|
|
}
|
|
|
|
$currentPath = 'promotion/current-package-set.json'
|
|
./.azurepipelines/validate-nuget-package-set.ps1 `
|
|
-PackageDirectory promotion `
|
|
-ManifestPath $currentPath `
|
|
-ExpectedVersion $expectedBaseVersion `
|
|
-RequireDebug `
|
|
-VerifySignatures
|
|
$current = Get-Content -LiteralPath $currentPath -Raw | ConvertFrom-Json
|
|
|
|
if ($current.packageCount -ne $manifest.packageCount -or
|
|
$current.symbolPackageCount -ne $manifest.symbolPackageCount -or
|
|
$current.debugPackageCount -ne $manifest.debugPackageCount) {
|
|
throw 'The downloaded package counts do not match the promotion manifest.'
|
|
}
|
|
|
|
$expectedArchives = @($manifest.archives | Sort-Object id, type, file) |
|
|
ConvertTo-Json -Depth 5 -Compress
|
|
$actualArchives = @($current.archives | Sort-Object id, type, file) |
|
|
ConvertTo-Json -Depth 5 -Compress
|
|
if ($actualArchives -cne $expectedArchives) {
|
|
throw 'The downloaded package names, identities, versions, or hashes have changed.'
|
|
}
|
|
|
|
Write-Host (
|
|
"Validated $($current.packageCount) exact package bytes at version " +
|
|
"$($current.basePackageVersion) from run $($env:RELEASE_RUN_ID).")
|
|
|
|
- name: Verify preview package ordering
|
|
# Last gate before an irreversible publication: the preview-only
|
|
# families carry the number committed in preview-version.props, which
|
|
# cannot track the growing "-preview.<height>" series that ordinary
|
|
# development publishes. Re-prove the ordering here (including on a
|
|
# dry run) rather than trusting that nothing was published between
|
|
# candidate creation and approval. See docs/ReleaseProcess.md.
|
|
shell: pwsh
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
./.azurepipelines/validate-preview-package-ordering.ps1 `
|
|
-ManifestPath 'promotion/current-package-set.json'
|
|
|
|
- name: Verify already-published package identity
|
|
# "--skip-duplicate" below makes a failed promotion recoverable by
|
|
# re-running the same candidate, but on its own it accepts *any*
|
|
# pre-existing id/version as a successful no-op. Prove first that every
|
|
# version this candidate already occupies really is this candidate's,
|
|
# so a foreign build that claimed an immutable version can never be
|
|
# mistaken for a completed publication. Runs on a dry run too: it is
|
|
# read-only and is exactly what a rehearsal should establish.
|
|
shell: pwsh
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
./.azurepipelines/assert-published-packages-match.ps1 `
|
|
-PackageDirectory promotion `
|
|
-ManifestPath 'promotion/current-package-set.json' `
|
|
-Feed 'nuget.org' `
|
|
-ExcludeDebugPackages
|
|
./.azurepipelines/assert-published-packages-match.ps1 `
|
|
-PackageDirectory promotion `
|
|
-ManifestPath 'promotion/current-package-set.json' `
|
|
-Feed 'GitHub Packages'
|
|
|
|
- name: NuGet login
|
|
if: ${{ !inputs.dry_run }}
|
|
id: login
|
|
uses: NuGet/login@v1
|
|
with:
|
|
user: ${{ secrets.NUGET_USER }}
|
|
|
|
- name: Push to nuget.org
|
|
if: ${{ !inputs.dry_run }}
|
|
shell: pwsh
|
|
env:
|
|
NUGET_API_KEY: ${{ steps.login.outputs.NUGET_API_KEY }}
|
|
run: |
|
|
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
|
$packages = @(Get-ChildItem promotion -Filter '*.nupkg' -File |
|
|
Where-Object {
|
|
$archive = [IO.Compression.ZipFile]::OpenRead($_.FullName)
|
|
try {
|
|
$nuspec = @($archive.Entries | Where-Object {
|
|
$_.FullName -notmatch '/' -and $_.FullName.EndsWith('.nuspec')
|
|
})
|
|
if ($nuspec.Count -ne 1) {
|
|
throw "Unable to identify package '$($_.Name)'."
|
|
}
|
|
$reader = [IO.StreamReader]::new($nuspec[0].Open())
|
|
try {
|
|
[xml]$metadata = $reader.ReadToEnd()
|
|
}
|
|
finally {
|
|
$reader.Dispose()
|
|
}
|
|
|
|
$id = [string]$metadata.package.metadata.id
|
|
-not $id.EndsWith(
|
|
'.Debug',
|
|
[StringComparison]::OrdinalIgnoreCase)
|
|
}
|
|
finally {
|
|
$archive.Dispose()
|
|
}
|
|
} |
|
|
Sort-Object Name)
|
|
if ($packages.Count -eq 0) {
|
|
throw 'The stable candidate contains no non-Debug packages to push to nuget.org.'
|
|
}
|
|
Write-Host (
|
|
"Publishing $($packages.Count) non-Debug package(s) to nuget.org. " +
|
|
'Debug package IDs remain in the signed candidate artifact and are ' +
|
|
'published only to GitHub Packages.')
|
|
foreach ($package in $packages) {
|
|
# --skip-duplicate keeps a partially completed promotion
|
|
# re-runnable. The preflight above rejects a foreign existing
|
|
# package; the post-push verification below closes the remaining
|
|
# race where another publisher claims the version between that
|
|
# check and this push.
|
|
dotnet nuget push $package.FullName `
|
|
--source 'https://api.nuget.org/v3/index.json' `
|
|
--symbol-source 'https://api.nuget.org/v3/index.json' `
|
|
--api-key $env:NUGET_API_KEY `
|
|
--skip-duplicate
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "nuget.org push failed for '$($package.Name)'."
|
|
}
|
|
}
|
|
./.azurepipelines/assert-published-packages-match.ps1 `
|
|
-PackageDirectory promotion `
|
|
-ManifestPath 'promotion/current-package-set.json' `
|
|
-Feed 'nuget.org' `
|
|
-ExcludeDebugPackages `
|
|
-RequirePresent
|
|
|
|
- name: Push to GitHub Packages
|
|
# nuget-publish.yml deliberately never pushes a stable candidate to
|
|
# any feed automatically (see its "Skip feed publication" step); this
|
|
# is the one place a stable release also gets mirrored to GitHub
|
|
# Packages, gated behind the same approval and dry-run switch as the
|
|
# nuget.org push above.
|
|
if: ${{ !inputs.dry_run }}
|
|
shell: pwsh
|
|
env:
|
|
GITHUB_PACKAGES_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
# GitHub Packages retains the complete signed candidate, including
|
|
# .Debug package IDs. Public nuget.org releases above intentionally
|
|
# exclude them; see docs/ReleaseProcess.md.
|
|
$packages = @(Get-ChildItem promotion -Filter '*.nupkg' -File | Sort-Object Name)
|
|
foreach ($package in $packages) {
|
|
# As above, the preflight and post-push checks jointly prove that
|
|
# a duplicate is this candidate rather than a package published
|
|
# in the check-then-push window.
|
|
dotnet nuget push $package.FullName `
|
|
--source 'https://nuget.pkg.github.com/OPCFoundation/index.json' `
|
|
--api-key $env:GITHUB_PACKAGES_TOKEN `
|
|
--skip-duplicate `
|
|
--no-symbols
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "GitHub Packages push failed for '$($package.Name)'."
|
|
}
|
|
}
|
|
./.azurepipelines/assert-published-packages-match.ps1 `
|
|
-PackageDirectory promotion `
|
|
-ManifestPath 'promotion/current-package-set.json' `
|
|
-Feed 'GitHub Packages' `
|
|
-GitHubToken $env:GITHUB_PACKAGES_TOKEN `
|
|
-RequirePresent
|
|
|
|
- name: Summary
|
|
if: always()
|
|
shell: pwsh
|
|
env:
|
|
RELEASE_RUN_ID: ${{ inputs.release_run_id }}
|
|
RELEASE_BRANCH: ${{ steps.source.outputs.branch }}
|
|
RELEASE_DRY_RUN: ${{ inputs.dry_run }}
|
|
run: |
|
|
$manifestPath = 'promotion/release-manifest.json'
|
|
if (Test-Path -LiteralPath $manifestPath) {
|
|
$manifest = Get-Content -LiteralPath $manifestPath -Raw | ConvertFrom-Json
|
|
$version = if ($manifest.schemaVersion -eq 2) {
|
|
$manifest.basePackageVersion
|
|
}
|
|
else {
|
|
$manifest.packageVersion
|
|
}
|
|
$count = $manifest.packageCount
|
|
}
|
|
else {
|
|
$version = 'unavailable'
|
|
$count = 'unavailable'
|
|
}
|
|
@"
|
|
### nuget.org release
|
|
|
|
- Source run: ``$($env:RELEASE_RUN_ID)``
|
|
- Source branch: ``$($env:RELEASE_BRANCH)``
|
|
- Version: ``$version``
|
|
- Packages: ``$count``
|
|
- Dry run: ``$($env:RELEASE_DRY_RUN)``
|
|
"@ | Add-Content -LiteralPath $env:GITHUB_STEP_SUMMARY
|