From 48bdb8fe7db0bb5fdfa642f544a9a876b0c17f59 Mon Sep 17 00:00:00 2001 From: Vitor Mattos Date: Thu, 24 Sep 2026 01:24:20 -0300 Subject: [PATCH 1/5] feat: add release-preflight action --- actions/release-preflight/action.yml | 78 ++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 actions/release-preflight/action.yml diff --git a/actions/release-preflight/action.yml b/actions/release-preflight/action.yml new file mode 100644 index 0000000..f7b543c --- /dev/null +++ b/actions/release-preflight/action.yml @@ -0,0 +1,78 @@ +# SPDX-FileCopyrightText: 2026 LibreCode coop and contributors +# SPDX-License-Identifier: AGPL-3.0-or-later + +name: Validate manual release preflight +description: Validate a simple manual Nextcloud app release before creating its GitHub Release. + +inputs: + version: + description: Release version in MAJOR.MINOR.PATCH form. + required: true + stable-branch: + description: Stable branch to release from. + required: true + current-ref: + description: Ref representing the checked-out release state. + required: true + repository: + description: Repository in owner/name form. + required: true + appinfo: + description: Path to appinfo/info.xml. + required: false + default: appinfo/info.xml + changelog: + description: Path to changelog file. + required: false + default: CHANGELOG.md + milestone: + description: Optional closed milestone that must have zero open issues. + required: false + default: '' + blocker-queries-json: + description: JSON array of GitHub issue search fragments that must return zero open items. + required: false + default: '[]' + github-token: + description: GitHub token used for milestone and issue checks. + required: true + +outputs: + result-file: + description: JSON file containing the preflight result. + value: ${{ steps.preflight.outputs.result-file }} + +runs: + using: composite + steps: + - id: setup + name: Setup release-tool + shell: bash + run: bash "${GITHUB_ACTION_PATH}/../_internal/setup.sh" + + - id: preflight + name: Validate release preflight + shell: bash + env: + GITHUB_TOKEN: ${{ inputs.github-token }} + RELEASE_TOOL_PATH: ${{ steps.setup.outputs.path }} + RELEASE_VERSION: ${{ inputs.version }} + RELEASE_STABLE_BRANCH: ${{ inputs.stable-branch }} + RELEASE_CURRENT_REF: ${{ inputs.current-ref }} + RELEASE_REPOSITORY: ${{ inputs.repository }} + RELEASE_APPINFO: ${{ inputs.appinfo }} + RELEASE_CHANGELOG: ${{ inputs.changelog }} + RELEASE_MILESTONE: ${{ inputs.milestone }} + RELEASE_BLOCKER_QUERIES: ${{ inputs.blocker-queries-json }} + run: | + set -euo pipefail + result="${RUNNER_TEMP}/release-preflight.json" + php "${RELEASE_TOOL_PATH}" release:preflight --version "${RELEASE_VERSION}" --stable-branch "${RELEASE_STABLE_BRANCH}" --current-ref "${RELEASE_CURRENT_REF}" --repository "${RELEASE_REPOSITORY}" --appinfo "${RELEASE_APPINFO}" --changelog "${RELEASE_CHANGELOG}" --milestone "${RELEASE_MILESTONE}" --blocker-queries-json "${RELEASE_BLOCKER_QUERIES}" --json | tee "${result}" + echo "result-file=${result}" >> "${GITHUB_OUTPUT}" + { + echo "## Release preflight" + echo + echo '~~~json' + cat "${result}" + echo '~~~' + } >> "${GITHUB_STEP_SUMMARY}" From c7bc16ce3589738a70005d135c23c5e810ca6a8a Mon Sep 17 00:00:00 2001 From: Vitor Mattos Date: Thu, 24 Sep 2026 01:24:22 -0300 Subject: [PATCH 2/5] feat: add appstore-publication-wait action --- actions/appstore-publication-wait/action.yml | 49 ++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 actions/appstore-publication-wait/action.yml diff --git a/actions/appstore-publication-wait/action.yml b/actions/appstore-publication-wait/action.yml new file mode 100644 index 0000000..8bf4f10 --- /dev/null +++ b/actions/appstore-publication-wait/action.yml @@ -0,0 +1,49 @@ +# SPDX-FileCopyrightText: 2026 LibreCode coop and contributors +# SPDX-License-Identifier: AGPL-3.0-or-later + +name: Verify App Store publication +description: Wait until a Nextcloud app release is visible in the App Store API. + +inputs: + app-name: + description: Nextcloud app id. + required: true + version: + description: Published app version. + required: true + platform: + description: Minimum Nextcloud platform version used for App Store lookup. + required: true + attempts: + description: Maximum lookup attempts. + required: false + default: '12' + delay-seconds: + description: Delay between attempts. + required: false + default: '10' + +runs: + using: composite + steps: + - id: setup + name: Setup release-tool + shell: bash + run: bash "${GITHUB_ACTION_PATH}/../_internal/setup.sh" + + - name: Verify App Store publication + shell: bash + env: + RELEASE_TOOL_PATH: ${{ steps.setup.outputs.path }} + RELEASE_APP_NAME: ${{ inputs.app-name }} + RELEASE_VERSION: ${{ inputs.version }} + RELEASE_PLATFORM: ${{ inputs.platform }} + RELEASE_ATTEMPTS: ${{ inputs.attempts }} + RELEASE_DELAY_SECONDS: ${{ inputs.delay-seconds }} + run: >- + php "${RELEASE_TOOL_PATH}" publication:wait-appstore + --app-name "${RELEASE_APP_NAME}" + --version "${RELEASE_VERSION}" + --platform "${RELEASE_PLATFORM}" + --attempts "${RELEASE_ATTEMPTS}" + --delay-seconds "${RELEASE_DELAY_SECONDS}" From 91b74cdd5b308310e0dd4a6c8ccd7c3ade815787 Mon Sep 17 00:00:00 2001 From: Vitor Mattos Date: Thu, 24 Sep 2026 01:24:34 -0300 Subject: [PATCH 3/5] chore: bump release-tool to 0.11.4 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 1a96df1..35ad344 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.11.3 +0.11.4 From ae8f945444d14dd3b79244a140dda19ea2ac74a2 Mon Sep 17 00:00:00 2001 From: Vitor Mattos Date: Thu, 24 Sep 2026 01:24:38 -0300 Subject: [PATCH 4/5] test: cover remaining consumer actions --- tests/Acceptance/ReleaseActionsTest.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/Acceptance/ReleaseActionsTest.php b/tests/Acceptance/ReleaseActionsTest.php index 110d477..919a8cb 100644 --- a/tests/Acceptance/ReleaseActionsTest.php +++ b/tests/Acceptance/ReleaseActionsTest.php @@ -10,7 +10,7 @@ final class ReleaseActionsTest extends TestCase { - private const array PUBLIC_ACTIONS = ['artifact-validate', 'metadata-inspect', 'post-merge', 'prepare', 'publication', 'release-notes', 'stable-select']; + private const array PUBLIC_ACTIONS = ['appstore-publication-wait', 'artifact-validate', 'metadata-inspect', 'post-merge', 'prepare', 'publication', 'release-notes', 'release-preflight', 'stable-select']; public function testPublicActionSurfaceIsExplicit(): void { @@ -104,6 +104,11 @@ public function testInternalBootstrapUsesExactVersionAndVerifiedChecksum(): void /** @return iterable, list}> */ public static function publicActionContracts(): iterable { + yield 'appstore-publication-wait' => [ + 'appstore-publication-wait', + ['app-name', 'version', 'platform', 'attempts', 'delay-seconds'], + [], + ]; yield 'artifact-validate' => [ 'artifact-validate', ['artifact', 'app-name', 'version'], @@ -177,6 +182,11 @@ public static function publicActionContracts(): iterable ['repository', 'branch', 'working-directory', 'from-ref', 'to-ref', 'fallback-limit', 'github-token'], ['changes-file', 'change-count', 'pull-request-count', 'commit-fallback-count'], ]; + yield 'release-preflight' => [ + 'release-preflight', + ['version', 'stable-branch', 'current-ref', 'repository', 'appinfo', 'changelog', 'milestone', 'blocker-queries-json', 'github-token'], + ['result-file'], + ]; yield 'stable-select' => [ 'stable-select', ['repository', 'branch', 'github-token'], From 98575fbf2610bd6aff2c6226f03f138ea4bd193e Mon Sep 17 00:00:00 2001 From: Vitor Mattos Date: Thu, 24 Sep 2026 01:24:40 -0300 Subject: [PATCH 5/5] docs: document complete public action surface --- docs/github-actions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/github-actions.md b/docs/github-actions.md index 32de1e2..3fba553 100644 --- a/docs/github-actions.md +++ b/docs/github-actions.md @@ -48,7 +48,7 @@ Do not run mutation logic for arbitrary pull requests. The public building blocks are: - lifecycle: `actions/prepare`, `actions/post-merge`, `actions/publication`; -- supporting release operations: `actions/stable-select`, `actions/artifact-validate`, `actions/metadata-inspect`, `actions/release-notes`. +- supporting release operations: `actions/stable-select`, `actions/artifact-validate`, `actions/metadata-inspect`, `actions/release-notes`, `actions/release-preflight`, `actions/appstore-publication-wait`. Consumers should call these Actions instead of downloading the PHAR or duplicating release-tool command bootstrap in workflow YAML. The Actions resolve the matching product version from this repository's `VERSION` file and verify the published PHAR checksum internally.