Skip to content

Commit 7c56345

Browse files
committed
sync with diff-common.sh
1 parent 9063bf4 commit 7c56345

File tree

15 files changed

+470
-148
lines changed

15 files changed

+470
-148
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ Then run the generated `scripts/bootstrap-new-package.sh` to create and push the
5656
### Template parameters (key ones)
5757

5858
| Parameter | Default | Description |
59-
|:--------------------- |:------- |:-------------------------------------------------------------------------- |
59+
| :-------------------- | :--------- | :------------------------------------------------------------------------- |
6060
| `--name` | (required) | Package/project name (PascalCase); repo becomes `vm2.<name>` |
6161
| `--initialVersion` | `0.1.0` | Initial version used in README/CHANGELOG; MinVer computes build versions |
6262
| `--license` | `MIT` | One of `MIT`, `Apache-2.0`, `BSD-3`; materializes LICENSE and SPDX headers |
@@ -141,7 +141,7 @@ Then run the generated `scripts/bootstrap-new-package.sh` to create and push the
141141
- `MIN_COVERAGE_PCT`: `80`%: Minimum code coverage percentage required
142142
- `NUGET_SERVER`: `github`: the NuGet server to publish to (supported values: 'github', 'nuget', or custom URI)
143143
- `SAVE_PACKAGE_ARTIFACTS`: `false`: Whether to save package artifacts after build/publish
144-
- `SEMVER_PRERELEASE_PREFIX`: `preview`: Prefix for the prerelease tag, e.g. 'preview', 'alpha', 'beta', 'rc', etc.
144+
- `MINVERDEFAULTPRERELEASEIDENTIFIERS`: `preview`: Prefix for the prerelease tag, e.g. 'preview.0', 'alpha', 'beta', 'rc', etc.
145145
1. Protect `main` with required checks and require PRs. Suggested check names:
146146
- `build` (job id from CI workflow "CI: Build, Test, Benchmark")
147147
- `test` (job id from CI workflow "CI: Build, Test, Benchmark")

templates/AddNewPackage/content/.github/workflows/CI.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ jobs:
5050
configuration: ${{ vars.CONFIGURATION }}
5151
min-coverage-pct: ${{ vars.MIN_COVERAGE_PCT }}
5252
max-regression-pct: ${{ vars.MAX_REGRESSION_PCT }}
53+
minver-tag-prefix: ${{ vars.MINVERTAGPREFIX || 'v' }}
54+
minver-prerelease-id: ${{ vars.MINVERDEFAULTPRERELEASEIDENTIFIERS || 'preview.0' }}
5355
outputs:
5456
build-projects: ${{ steps.init-params.outputs.build-projects }}
5557
test-projects: ${{ steps.init-params.outputs.test-projects }}
@@ -60,6 +62,8 @@ jobs:
6062
preprocessor-symbols: ${{ steps.init-params.outputs.preprocessor-symbols }}
6163
min-coverage-pct: ${{ steps.init-params.outputs.min-coverage-pct }}
6264
max-regression-pct: ${{ steps.init-params.outputs.max-regression-pct }}
65+
minver-tag-prefix: ${{ steps.init-params.outputs.minver-tag-prefix }}
66+
minver-prerelease-id: ${{ steps.init-params.outputs.minver-prerelease-id }}
6367
steps:
6468
- name: Gather parameters
6569
id: init-params
@@ -73,6 +77,8 @@ jobs:
7377
configuration='${{ env.configuration }}'
7478
min_coverage_pct='${{ env.min-coverage-pct }}'
7579
max_regression_pct='${{ env.max-regression-pct }}'
80+
minver_tag_prefix='${{ env.minver-tag-prefix }}'
81+
minver_prerelease_id='${{ env.minver-prerelease-id }}'
7682
7783
if [ '${{ github.event_name }}' == "push" ]; then
7884
# Set the values for push events, and add SHORT_RUN to preprocessor_symbols for faster benchmark tests (less precise, yet acceptable for CI runs).
@@ -104,6 +110,8 @@ jobs:
104110
echo "configuration=${configuration}"
105111
echo "min-coverage-pct=${min_coverage_pct}"
106112
echo "max-regression-pct=${max_regression_pct}"
113+
echo "minver-tag-prefix=${minver_tag_prefix}"
114+
echo "minver-prerelease-id=${minver_prerelease_id}"
107115
} >> $GITHUB_OUTPUT
108116
109117
call-ci:
@@ -129,3 +137,5 @@ jobs:
129137
benchmark-projects: ${{ needs.get-params.outputs.benchmark-projects }}
130138
min-coverage-pct: ${{ fromJSON(needs.get-params.outputs.min-coverage-pct) }}
131139
max-regression-pct: ${{ fromJSON(needs.get-params.outputs.max-regression-pct) }}
140+
minver-tag-prefix: ${{ needs.get-params.outputs.minver-tag-prefix }}
141+
minver-prerelease-id: ${{ needs.get-params.outputs.minver-prerelease-id }}

templates/AddNewPackage/content/.github/workflows/Prerelease.yaml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ on:
99

1010
workflow_dispatch:
1111
inputs:
12-
semver-prerelease-prefix:
12+
minver-prerelease-id:
1313
description: "Prerelease prefix (e.g. preview, alpha, beta, rc1, etc.)"
1414
type: string
1515
required: true
@@ -36,34 +36,34 @@ jobs:
3636
package-projects: ${{ steps.init-params.outputs.package-projects }}
3737
nuget-server: ${{ steps.init-params.outputs.nuget-server }}
3838
minver-tag-prefix: ${{ steps.init-params.outputs.minver-tag-prefix }}
39-
semver-prerelease-prefix: ${{ steps.init-params.outputs.semver-prerelease-prefix }}
39+
minver-prerelease-id: ${{ steps.init-params.outputs.minver-prerelease-id }}
4040
reason: ${{ steps.init-params.outputs.reason }}
4141
save-package-artifacts: ${{ steps.init-params.outputs.save-package-artifacts }}
4242
steps:
4343
- name: Gather parameters
4444
id: init-params
4545
shell: bash
4646
run: |
47-
dotnet_version='${{ vars.DOTNET_VERSION }}'
4847
package_projects='${{ env.PACKAGE_PROJECTS }}'
4948
nuget_server='${{ env.NUGET_SERVER }}'
49+
dotnet_version='${{ vars.DOTNET_VERSION }}'
5050
minver_tag_prefix='${{ vars.MINVERTAGPREFIX || 'v' }}'
51-
semver_prerelease_prefix='${{ vars.SEMVER_PRERELEASE_PREFIX || 'preview' }}'
52-
reason=$(printf "%s %s" "$semver_prerelease_prefix" "pre-release (PR to main)")
51+
minver_prerelease_id='${{ vars.MINVERDEFAULTPRERELEASEIDENTIFIERS || 'preview.0' }}'
52+
reason="$minver_prerelease_id pre-release (PR to main)"
5353
save_package_artifacts='${{ vars.SAVE_PACKAGE_ARTIFACTS || 'false' }}'
5454
5555
if [ '${{ github.event_name }}' == "workflow_dispatch" ]; then
56-
semver_prerelease_prefix='${{ inputs.semver-prerelease-prefix }}'
56+
minver_prerelease_id='${{ inputs.minver-prerelease-id }}'
5757
reason='${{ inputs.reason }}'
5858
fi
5959
6060
# Set the outputs:
6161
{
62-
echo "dotnet-version=${dotnet_version}"
6362
echo "package-projects=${package_projects}"
6463
echo "nuget-server=${nuget_server}"
64+
echo "dotnet-version=${dotnet_version}"
6565
echo "minver-tag-prefix=${minver_tag_prefix}"
66-
echo "semver-prerelease-prefix=${semver_prerelease_prefix}"
66+
echo "minver-prerelease-id=${minver_prerelease_id}"
6767
echo "reason=${reason}"
6868
echo "save-package-artifacts=${save_package_artifacts}"
6969
} >> $GITHUB_OUTPUT
@@ -98,6 +98,6 @@ jobs:
9898
package-projects: ${{ needs.get-params.outputs.package-projects }}
9999
nuget-server: ${{ needs.get-params.outputs.nuget-server }}
100100
minver-tag-prefix: ${{ needs.get-params.outputs.minver-tag-prefix }}
101-
semver-prerelease-prefix: ${{ needs.get-params.outputs.semver-prerelease-prefix }}
101+
minver-prerelease-id: ${{ needs.get-params.outputs.minver-prerelease-id }}
102102
reason: ${{ needs.get-params.outputs.reason }}
103103
save-package-artifacts: ${{ fromJson(needs.get-params.outputs.save-package-artifacts) }}

templates/AddNewPackage/content/.github/workflows/Release.yaml

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,14 @@ jobs:
2626
${{
2727
github.event_name == 'workflow_dispatch' ||
2828
!contains(github.ref_name,'-') &&
29-
startsWith(github.ref, format('refs/tags/%s', vars.MinVerTagPrefix || 'v'))
29+
startsWith(github.ref, format('refs/tags/%s', vars.MINVERTAGPREFIX || 'v'))
3030
}}
3131
outputs:
32+
dotnet-version: ${{ steps.init-params.outputs.dotnet-version }}
3233
package-projects: ${{ steps.init-params.outputs.package-projects }}
3334
nuget-server: ${{ steps.init-params.outputs.nuget-server }}
35+
minver-tag-prefix: ${{ steps.init-params.outputs.minver-tag-prefix }}
36+
reason: ${{ steps.init-params.outputs.reason }}
3437
save-package-artifacts: ${{ steps.init-params.outputs.save-package-artifacts }}
3538
steps:
3639
- name: Gather parameters
@@ -39,12 +42,22 @@ jobs:
3942
run: |
4043
package_projects='${{ env.PACKAGE_PROJECTS }}'
4144
nuget_server='${{ env.NUGET_SERVER }}'
45+
dotnet_version='${{ vars.DOTNET_VERSION }}'
46+
minver_tag_prefix='${{ vars.MINVERTAGPREFIX || 'v' }}'
47+
reason="Stable Release (main tagged release)"
4248
save_package_artifacts='${{ vars.SAVE_PACKAGE_ARTIFACTS || 'false' }}'
4349
50+
if [ '${{ github.event_name }}' == "workflow_dispatch" ]; then
51+
reason='${{ inputs.reason }}'
52+
fi
53+
4454
# Set the outputs:
4555
{
4656
echo "package-projects=${package_projects}"
4757
echo "nuget-server=${nuget_server}"
58+
echo "dotnet-version=${dotnet_version}"
59+
echo "minver-tag-prefix=${minver_tag_prefix}"
60+
echo "reason=${reason}"
4861
echo "save-package-artifacts=${save_package_artifacts}"
4962
} >> $GITHUB_OUTPUT
5063
@@ -77,5 +90,6 @@ jobs:
7790
dotnet-version: ${{ vars.DOTNET_VERSION }}
7891
package-projects: ${{ needs.get-params.outputs.package-projects }}
7992
nuget-server: ${{ needs.get-params.outputs.nuget-server }}
80-
reason: ${{ inputs.reason }}
93+
reason: ${{ needs.get-params.outputs.reason }}
8194
save-package-artifacts: ${{ fromJson(needs.get-params.outputs.save-package-artifacts) }}
95+
minver-tag-prefix: ${{ needs.get-params.outputs.minver-tag-prefix }}

templates/AddNewPackage/content/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ A starter vm2 package scaffold. Customize the code, tests, benchmarks, docs, and
1818
dotnet run --project test/MyPackage.Tests/MyPackage.Tests.csproj`
1919
```
2020

21-
- from **CLI**, if it is already built in **CLI** or **VSCode** (MTP v2):
21+
- from **CLI**, if it is already built in **CLI** or **VSCode** (MTP v2):
2222
- any OS or shell:
2323

2424
```bash
@@ -88,7 +88,7 @@ A starter vm2 package scaffold. Customize the code, tests, benchmarks, docs, and
8888
- `CONFIGURATION`: `Release`: the build configuration to use (e.g., Release or Debug)
8989
- `NUGET_SERVER`: `github`: the NuGet server to publish to (supported values: 'github', 'nuget', or custom URI)
9090
- `MINVERTAGPREFIX`: `v`: Prefix for git tags to be recognized by MinVer
91-
- `SEMVER_PRERELEASE_PREFIX`: `preview`: Prefix for the prerelease tag, e.g. 'preview', 'alpha', 'beta', 'rc', etc.
91+
- `MINVERDEFAULTPRERELEASEIDENTIFIERS`: `preview`: Prefix for the prerelease tag, e.g. 'preview.0', 'alpha', 'beta', 'rc', etc.
9292
- `SAVE_PACKAGE_ARTIFACTS`: `false`: Whether to save package artifacts after build/publish
9393
- `MIN_COVERAGE_PCT`: `80`%: Minimum code coverage percentage required
9494
- `MAX_REGRESSION_PCT`: `20`%: Maximum allowed regression percentage

templates/AddNewPackage/content/scripts/_common.diagnostics.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ declare -ix errors=0
66
## Shell function to log error messages to the standard output and to the GitHub step summary (github_step_summary).
77
## Increments the error counter.
88
## Usage: `error <message1> [<message2> ...]`, or `echo "message" | error`, or error <<< "message"
9-
# shellcheck disable=SC2154 # variable is referenced but not assigned.
109
function error()
1110
{
1211
if [[ $# -gt 0 ]]; then
@@ -78,6 +77,10 @@ function trace() {
7877
declare last_command
7978
declare current_command="$BASH_COMMAND"
8079

80+
# on_debug and on_exit are trying to cooperatively do error handling when exit is invoked. To be effective, after
81+
# sourcing this script, set these signal traps:
82+
# trap on_debug DEBUG
83+
# trap on_exit EXIT
8184
function on_debug() {
8285
# keep track of the last executed command
8386
last_command="$current_command"

templates/AddNewPackage/content/scripts/_common.github.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ declare -x semverTagReleaseRegex
2828
declare -x semverTagPrereleaseRegex
2929

3030
## Shell function to create the regular expressions above for tags comprising a given prefix with a semantic version.
31-
## Call once when the tag prefix is known. For example: create_tag_regexes "v". It might be a good idea to declare the resulting
31+
## Call once when the tag prefix is known. For example: create_tag_regexes 'v'. It might be a good idea to declare the resulting
3232
## variables as readonly after calling this function:
3333
## declare -xr semverTagRegex
3434
## declare -xr semverTagReleaseRegex
@@ -188,7 +188,7 @@ function args_to_github_output()
188188
## Validates if the first argument is a name of a valid JSON array of project paths, if it is null, empty or empty array, it use
189189
## the second parameter as default value, usually `[""]`.
190190
# shellcheck disable=SC2154 # variable is referenced but not assigned.
191-
function validate_projects() {
191+
function are_safe_projects() {
192192
local -n projects=$1
193193
local default_projects=${2:-'[""]'}
194194

templates/AddNewPackage/content/scripts/_common.predicates.sh

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/bin/bash
22

3-
if ! declare -pF "error" > /dev/null; then
3+
# shellcheck disable=SC2154 # variable is referenced but not assigned.
4+
if ! declare -pF "error" > "$_ignore"; then
45
semver_dir="$(dirname "${BASH_SOURCE[0]}")"
56
source "$semver_dir/_common.diagnostics.sh"
67
fi
@@ -74,10 +75,11 @@ function is_in() {
7475
function has_errors()
7576
{
7677
if ((errors > 0)); then
77-
error "$errors error(s) encountered. Please fix the issues and try again." >&2
7878
if [[ -n $1 ]]; then
79-
usage
79+
usage "❌ ERROR: $errors error(s) encountered. Please fix the above issues and try again."
8080
exit 2
81+
else
82+
error "$errors error(s) encountered. Please fix the above issues and try again."
8183
fi
8284
return 1
8385
fi
@@ -99,29 +101,29 @@ function is_git_repo()
99101
return 2
100102
fi
101103

102-
[[ -d $1 ]] && git -C "$1" rev-parse --is-inside-work-tree &>/dev/null
104+
[[ -d $1 ]] && git -C "$1" rev-parse --is-inside-work-tree &>"$_ignore"
103105
}
104106

105107
## Tests if the current commit in the specified directory is on the latest stable tag.
106108
## Usage: is_on_or_after_latest_stable_tag <directory> <stable-tag-regex> [<skip-fetch>]
107109
function is_latest_stable_tag()
108110
{
109-
if [[ $# != 2 ]]; then
111+
if [[ $# -lt 2 || $# -gt 3 ]]; then
110112
error "The function is_latest_stable_tag() takes 2 arguments: directory and regular expression for stable tag." \
111113
"A third argument may be specified to fetch latest in main changes from remote."
112114
fi
113-
if [[ ! -d $1 ]]; then
115+
if [[ ! -d "$1" ]]; then
114116
error "The specified directory '$1' does not exist."
115117
fi
116-
if [[ -z $2 ]]; then
118+
if [[ -z "$2" ]]; then
117119
error "The regular expression for stable tag cannot be empty."
118120
fi
119121
((errors == 0 )) || return 2
120122

121123
local latest_tag current_commit tag_commit
122124

123125
is_git_repo "$1" || return 2
124-
if [[ $3 != "true" ]]; then
126+
if [[ $# -eq 3 && "$3" != "true" ]]; then
125127
git -C "$1" fetch origin main --quiet
126128
fi
127129

@@ -131,7 +133,7 @@ function is_latest_stable_tag()
131133

132134
current_commit=$(git -C "$1" rev-parse HEAD)
133135

134-
tag_commit=$(git -C "$1" rev-parse "$latest_tag^{commit}" 2>/dev/null)
136+
tag_commit=$(git -C "$1" rev-parse "$latest_tag^{commit}" 2>"$_ignore")
135137

136138
[[ "$current_commit" == "$tag_commit" ]]
137139
}
@@ -140,66 +142,66 @@ function is_latest_stable_tag()
140142
## Usage: is_after_latest_stable_tag <directory> <stable-tag-regex> [<skip-fetch>]
141143
function is_after_latest_stable_tag()
142144
{
143-
if [[ $# != 2 ]]; then
145+
if [[ $# -lt 2 || $# -gt 3 ]]; then
144146
error "The function is_after_latest_stable_tag() takes 2 arguments: directory and regular expression for stable tag." \
145147
"A third argument may be specified to fetch latest in main changes from remote."
146148
fi
147-
if [[ ! -d $1 ]]; then
149+
if [[ ! -d "$1" ]]; then
148150
error "The specified directory '$1' does not exist."
149151
fi
150-
if [[ -z $2 ]]; then
152+
if [[ -z "$2" ]]; then
151153
error "The regular expression for stable tag cannot be empty."
152154
fi
153155
((errors == 0 )) || return 2
154156

155157
local latest_tag tag_commit commits_after
156158

157159
is_git_repo "$1" || return 2
158-
if [[ $3 != "true" ]]; then
160+
if [[ $# -eq 3 && "$3" != "true" ]]; then
159161
git -C "$1" fetch origin main --quiet
160162
fi
161163

162164
# Get latest stable tag (excludes pre-release tags with -)
163165
latest_tag=$(git -C "$1" tag | grep -E "$2" | sort -V | tail -n1)
164166
[[ -n $latest_tag ]] || return 1
165167

166-
tag_commit=$(git -C "$1" rev-parse "$latest_tag^{commit}" 2>/dev/null)
168+
tag_commit=$(git -C "$1" rev-parse "$latest_tag^{commit}" 2>"$_ignore")
167169

168170
# Check if current commit is after the latest stable tag
169-
commits_after=$(git -C "$1" rev-list "$tag_commit..HEAD" --count 2>/dev/null)
171+
commits_after=$(git -C "$1" rev-list "$tag_commit..HEAD" --count 2>"$_ignore")
170172
[[ $commits_after -gt 0 ]]
171173
}
172174

173175
## Tests if the current commit in the specified directory is on or after the latest stable tag.
174176
## Usage: is_on_or_after_latest_stable_tag <directory> <stable-tag-regex> [<skip-fetch>]
175177
function is_on_or_after_latest_stable_tag()
176178
{
177-
if [[ $# != 2 ]]; then
179+
if [[ $# -lt 2 || $# -gt 3 ]]; then
178180
error "The function is_on_or_after_latest_stable_tag() takes 2 arguments: directory and regular expression for stable tag." \
179181
"A third argument may be specified to fetch latest in main changes from remote."
180182
fi
181-
if [[ ! -d $1 ]]; then
183+
if [[ ! -d "$1" ]]; then
182184
error "The specified directory '$1' does not exist."
183185
fi
184-
if [[ -z $2 ]]; then
186+
if [[ -z "$2" ]]; then
185187
error "The regular expression for stable tag cannot be empty."
186188
fi
187189
((errors == 0 )) || return 2
188190

189191
local latest_tag tag_commit
190192

191193
is_git_repo "$1" || return 2
192-
if [[ $3 != "true" ]]; then
194+
if [[ $# -eq 3 && "$3" != "true" ]]; then
193195
git -C "$1" fetch origin main --quiet
194196
fi
195197

196198
# Get latest stable tag
197199
latest_tag=$(git -C "$1" tag | grep -E "$2" | sort -V | tail -n1)
198200
[[ -n $latest_tag ]] || return 1
199201

200-
tag_commit=$(git -C "$1" rev-parse "$latest_tag^{commit}" 2>/dev/null)
202+
tag_commit=$(git -C "$1" rev-parse "$latest_tag^{commit}" 2>"$_ignore")
201203

202204
# Check if current commit is on or after the latest stable tag
203205
# Returns 0 if tag commit is an ancestor of HEAD (i.e., HEAD is at or after the tag)
204-
git -C "$1" merge-base --is-ancestor "$tag_commit" HEAD &>/dev/null
206+
git -C "$1" merge-base --is-ancestor "$tag_commit" HEAD &>"$_ignore"
205207
}

0 commit comments

Comments
 (0)