From 10536f63dd35696a956fd4d73ba600e2191c575a Mon Sep 17 00:00:00 2001 From: Compot Developer Date: Sun, 18 Oct 2026 12:58:39 +0000 Subject: [PATCH 1/2] ci: the build workflow counts as build, a no-release label skips the version; publish only the head of main (#57, #58) --- .github/check-version.sh | 26 +++++++++++++++++++------- .github/workflows/build.yml | 21 +++++++++++++++++++-- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/.github/check-version.sh b/.github/check-version.sh index ca236e3..0034dee 100755 --- a/.github/check-version.sh +++ b/.github/check-version.sh @@ -7,11 +7,16 @@ # MAJOR.MINOR.PATCH without leading zeros, greater than the base one, and # have its section in CHANGELOG.md ("## — YYYY-MM-DD") that the # base branch does not have yet. The sources, android/ (except its unit -# tests), the Makefile, ci/ and scripts/ count as code or build, without the -# Markdown files in them (server/README.md, android/README.md); docs, -# tests/, bench/, screenshots and the workflows in .github/ need no new -# version. The format is checked only when the version changes, so the -# MAJOR.MM versions up to 1.12 stay valid until the next code change. +# tests), the Makefile, ci/, scripts/ and the build workflow +# (.github/workflows/build.yml) count as code or build, without the Markdown +# files in them (server/README.md, android/README.md); docs, tests/, bench/, +# screenshots and the rest of .github/ need no new version. The script does +# not tell the build steps of the workflow from its test or release steps: +# NO_RELEASE=true (the pull request's `no-release` label) lets a change to +# the code or the build through without a new version, for changes that +# leave the release files as they are (a test or release step, a comment). +# The format is checked only when the version changes, so the MAJOR.MM +# versions up to 1.12 stay valid until the next code change. # # Usage: .github/check-version.sh [BASE] (default origin/main; CI passes # HEAD^1, the base side of the pull request's merge commit) @@ -21,7 +26,7 @@ set -eu base=${1:-origin/main} header=include/vtesse/version.h -code="include netcore cli vtun port server scripts third_party tools android Makefile ci" +code="include netcore cli vtun port server scripts third_party tools android Makefile ci .github/workflows/build.yml" # The one VTESSE_VERSION definition (comments and other text do not count). ver() { @@ -42,9 +47,16 @@ changed=$(git diff --name-only "$base"...HEAD -- $code ':(exclude)android/app/sr ':(exclude,glob)**/*.md') if [ "$new" = "$old" ]; then + if [ -n "$changed" ] && [ "${NO_RELEASE:-}" = true ]; then + echo "::notice::code or build changed, VTESSE_VERSION stays $old: the no-release" \ + "label says the release files do not change" + echo "$changed" + exit 0 + fi if [ -n "$changed" ]; then echo "::error::code or build changed, VTESSE_VERSION is still $old:" \ - "bump PATCH (fix) or MINOR (feature) and add its CHANGELOG.md section" + "bump PATCH (fix) or MINOR (feature) and add its CHANGELOG.md section," \ + "or label the pull request no-release if the release files do not change" echo "$changed" exit 1 fi diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f7184eb..1a5835e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,7 +18,9 @@ # MAJOR.MINOR.PATCH) and its notes are one short line; the change history lives # in CHANGELOG.md. No versioned releases are kept. # On pull requests, .github/check-version.sh checks that a change to the code or -# the build comes with a new VTESSE_VERSION and its CHANGELOG.md section. +# the build (this workflow included) comes with a new VTESSE_VERSION and its +# CHANGELOG.md section, unless the pull request is labelled no-release: a change +# that leaves the release files as they are. Only the head of main is published. # name: VTesse CI @@ -28,6 +30,8 @@ on: branches: [main] pull_request: branches: [main] + # labeled / unlabeled: the version check reads the no-release label + types: [opened, synchronize, reopened, labeled, unlabeled] workflow_dispatch: # One run per branch: on pull requests a newer push cancels the older run; on @@ -55,6 +59,9 @@ jobs: # base it was made from, so both versions come from the same base. - name: Code changes come with a new version run: .github/check-version.sh HEAD^1 + env: + # a change that leaves the release files as they are may skip the new version + NO_RELEASE: ${{ contains(github.event.pull_request.labels.*.name, 'no-release') }} # ------------------------------------------------------------------ tests tests: @@ -244,12 +251,22 @@ jobs: cp scripts/vtesse-hook.sh scripts/vtesse-udhcpc.script scripts/S99vtesse scripts/vtesse.init release/ ls -l release + # Only the head of main is published: a re-run of an older run, or a run that + # finishes after a newer push, must not put an older commit back as "latest". + # Checked last, right before anything is deleted. - name: Publish "latest" + id: publish env: GH_TOKEN: ${{ github.token }} VER: ${{ steps.vars.outputs.ver }} VTUN: ${{ steps.vars.outputs.vtun }} run: | + head=$(git ls-remote origin refs/heads/main | cut -f 1) + if [ "$head" != "$GITHUB_SHA" ]; then + echo "::notice::main is at ${head:0:7} now, not ${GITHUB_SHA::7}: not published" + exit 0 + fi + echo "published=true" >> "$GITHUB_OUTPUT" gh release delete latest --cleanup-tag --yes 2>/dev/null || true gh release create latest release/* \ --latest \ @@ -260,7 +277,7 @@ jobs: # The Telegram channel gets the APK of every new version, as in OpenIPC/decoder (#33). # Organization secrets; a failed upload is reported but does not fail the release. - name: Telegram - if: steps.vars.outputs.new == 'true' + if: steps.vars.outputs.new == 'true' && steps.publish.outputs.published == 'true' env: TG_TOKEN: ${{ secrets.TELEGRAM_TOKEN_BOT_OPENIPC }} TG_CHANNEL: ${{ secrets.TELEGRAM_CHANNEL_OPENIPC_DEV }} From 178f9ff44cb8a67d1d4e5c2e91035094b2cbb34a Mon Sep 17 00:00:00 2001 From: Compot Developer Date: Sun, 18 Oct 2026 13:09:43 +0000 Subject: [PATCH 2/2] ci: a failed head lookup fails the release instead of skipping it (#57) --- .github/workflows/build.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1a5835e..ec7bcc1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -261,7 +261,13 @@ jobs: VER: ${{ steps.vars.outputs.ver }} VTUN: ${{ steps.vars.outputs.vtun }} run: | - head=$(git ls-remote origin refs/heads/main | cut -f 1) + # a failed or empty lookup fails the step: only a newer head skips the publication + ref=$(git ls-remote --exit-code origin refs/heads/main) || + { echo "::error::cannot read the head of main"; exit 1; } + head=$(printf '%s\n' "$ref" | cut -f 1) + if ! printf '%s\n' "$head" | grep -Eqx '[0-9a-f]{40}'; then + echo "::error::unexpected head of main: \"$head\""; exit 1 + fi if [ "$head" != "$GITHUB_SHA" ]; then echo "::notice::main is at ${head:0:7} now, not ${GITHUB_SHA::7}: not published" exit 0