diff --git a/.github/workflows/appstore-build-publish.yml b/.github/workflows/appstore-build-publish.yml index f71e02e..2f84a4a 100644 --- a/.github/workflows/appstore-build-publish.yml +++ b/.github/workflows/appstore-build-publish.yml @@ -188,12 +188,32 @@ jobs: cd ${{ env.APP_NAME }}/build/artifacts tar -zcvf ${{ env.APP_NAME }}.tar.gz ${{ env.APP_NAME }} - - name: Validate release artifact - uses: LibreCodeCoop/github-workflows/actions/release-artifact-validate@622599cc128ec55007b443d2908f78da930b8a21 # v0.5.0 + - name: Set up PHP 8.3 for release-tool + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # 2.37.2 with: - artifact: ${{ env.APP_NAME }}/build/artifacts/${{ env.APP_NAME }}.tar.gz - app-name: ${{ env.APP_NAME }} - version: ${{ env.APP_VERSION }} + php-version: '8.3' + coverage: none + + - id: release-tool + name: Setup release-tool v0.11.1 + shell: bash + run: | + set -euo pipefail + base="https://github.com/LibreCodeCoop/release-tool/releases/download/v0.11.1" + curl --fail --silent --show-error --location "${base}/release-tool.phar" -o "${RUNNER_TEMP}/release-tool.phar" + curl --fail --silent --show-error --location "${base}/release-tool.phar.sha256" -o "${RUNNER_TEMP}/release-tool.phar.sha256" + (cd "${RUNNER_TEMP}" && sha256sum --check release-tool.phar.sha256) + echo "path=${RUNNER_TEMP}/release-tool.phar" >> "${GITHUB_OUTPUT}" + + - name: Validate release artifact + shell: bash + env: + RELEASE_TOOL_PATH: ${{ steps.release-tool.outputs.path }} + run: >- + php "${RELEASE_TOOL_PATH}" artifact:validate-package + --artifact "${APP_NAME}/build/artifacts/${APP_NAME}.tar.gz" + --app-name "${APP_NAME}" + --expected-version "${APP_VERSION}" - name: Attach tarball to github release uses: svenstaro/upload-release-action@29e53e917877a24fad85510ded594ab3c9ca12de # 2.11.5 @@ -214,8 +234,12 @@ jobs: app_private_key: ${{ secrets.APP_PRIVATE_KEY }} - name: Verify App Store publication - uses: LibreCodeCoop/github-workflows/actions/verify-appstore-publication@0bb30136a7fcb7e70b7ae579addeeda882f4c457 # v0.2.0 - with: - app-name: ${{ env.APP_NAME }} - version: ${{ env.APP_VERSION }} - nextcloud-platform: ${{ fromJSON(steps.appinfo.outputs.result).nextcloud.min-version }} + shell: bash + env: + RELEASE_TOOL_PATH: ${{ steps.release-tool.outputs.path }} + NEXTCLOUD_PLATFORM: ${{ fromJSON(steps.appinfo.outputs.result).nextcloud.min-version }} + run: >- + php "${RELEASE_TOOL_PATH}" publication:wait-appstore + --app-name "${APP_NAME}" + --version "${APP_VERSION}" + --platform "${NEXTCLOUD_PLATFORM}" diff --git a/.github/workflows/release-nextcloud-app.yml b/.github/workflows/release-nextcloud-app.yml index 3bb9a7a..0ca92b9 100644 --- a/.github/workflows/release-nextcloud-app.yml +++ b/.github/workflows/release-nextcloud-app.yml @@ -55,14 +55,50 @@ jobs: fetch-depth: 0 persist-credentials: false - - name: Validate release plan - uses: LibreCodeCoop/github-workflows/actions/release-plan@94ad33acf3cdf261db5b90a2297f92325c48c5d2 # v0.2.0 + - name: Set up PHP 8.3 for release-tool + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # 2.37.2 with: - version: ${{ inputs.version }} - stable-branch: ${{ inputs.stable_branch }} - milestone: ${{ inputs.milestone }} - blocker-queries: ${{ inputs.blocker_queries }} - github-token: ${{ github.token }} + php-version: '8.3' + coverage: none + + - id: release-tool + name: Setup release-tool v0.11.2 + shell: bash + run: | + set -euo pipefail + base="https://github.com/LibreCodeCoop/release-tool/releases/download/v0.11.2" + curl --fail --silent --show-error --location "${base}/release-tool.phar" -o "${RUNNER_TEMP}/release-tool.phar" + curl --fail --silent --show-error --location "${base}/release-tool.phar.sha256" -o "${RUNNER_TEMP}/release-tool.phar.sha256" + (cd "${RUNNER_TEMP}" && sha256sum --check release-tool.phar.sha256) + echo "path=${RUNNER_TEMP}/release-tool.phar" >> "${GITHUB_OUTPUT}" + + - name: Validate release plan + shell: bash + env: + GITHUB_TOKEN: ${{ github.token }} + RELEASE_TOOL_PATH: ${{ steps.release-tool.outputs.path }} + RELEASE_VERSION: ${{ inputs.version }} + STABLE_BRANCH: ${{ inputs.stable_branch }} + RELEASE_MILESTONE: ${{ inputs.milestone }} + BLOCKER_QUERIES: ${{ inputs.blocker_queries }} + run: | + set -euo pipefail + plan="${RUNNER_TEMP}/release-preflight.json" + php "${RELEASE_TOOL_PATH}" release:preflight \ + --version "${RELEASE_VERSION}" \ + --stable-branch "${STABLE_BRANCH}" \ + --current-ref "${STABLE_BRANCH}" \ + --repository "${GITHUB_REPOSITORY}" \ + --milestone "${RELEASE_MILESTONE}" \ + --blocker-queries-json "${BLOCKER_QUERIES}" \ + --json | tee "${plan}" + { + echo "## Release preflight" + echo + echo '~~~json' + cat "${plan}" + echo '~~~' + } >> "${GITHUB_STEP_SUMMARY}" - name: Validate publication credentials env: diff --git a/.github/workflows/sync-workflow-templates.yml b/.github/workflows/sync-workflow-templates.yml index 2bc4d1e..d7aacf2 100644 --- a/.github/workflows/sync-workflow-templates.yml +++ b/.github/workflows/sync-workflow-templates.yml @@ -6,8 +6,11 @@ # SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors # SPDX-License-Identifier: MIT -# This workflow will update all workflow templates -# Additionally it will reapply `workflow.yml.patch` files after syncing and only then commit the result +# This workflow will update all workflow templates. +# Additionally it will reapply workflow.yml.patch files after syncing and only then commit the result. +# +# Authentication is selected explicitly with vars.WORKFLOW_SYNC_AUTH_MODE. +# See docs/cross-repository-automation.md for modes, credentials and GITHUB_TOKEN limitations. name: Update workflows on: workflow_dispatch: @@ -39,18 +42,99 @@ jobs: with: require: admin - - name: Create GitHub App token - id: app-token + - name: Validate workflow sync authentication + shell: bash + env: + AUTH_MODE: ${{ vars.WORKFLOW_SYNC_AUTH_MODE || 'librecode-app' }} + LIBRECODE_APP_ID: ${{ vars.LIBRECODE_WORKFLOW_APP_ID }} + LIBRECODE_APP_PRIVATE_KEY: ${{ secrets.LIBRECODE_WORKFLOW_APP_PRIVATE_KEY }} + CONSUMER_APP_ID: ${{ vars.WORKFLOW_SYNC_APP_ID }} + CONSUMER_APP_PRIVATE_KEY: ${{ secrets.WORKFLOW_SYNC_APP_PRIVATE_KEY }} + CONSUMER_TOKEN: ${{ secrets.WORKFLOW_SYNC_TOKEN }} + run: | + set -euo pipefail + + case "${AUTH_MODE}" in + librecode-app) + [[ -n "${LIBRECODE_APP_ID}" && -n "${LIBRECODE_APP_PRIVATE_KEY}" ]] || { + echo "::error::librecode-app requires LIBRECODE_WORKFLOW_APP_ID and LIBRECODE_WORKFLOW_APP_PRIVATE_KEY" + exit 1 + } + ;; + github-app) + [[ -n "${CONSUMER_APP_ID}" && -n "${CONSUMER_APP_PRIVATE_KEY}" ]] || { + echo "::error::github-app requires WORKFLOW_SYNC_APP_ID and WORKFLOW_SYNC_APP_PRIVATE_KEY" + exit 1 + } + ;; + token) + [[ -n "${CONSUMER_TOKEN}" ]] || { + echo "::error::token mode requires WORKFLOW_SYNC_TOKEN" + exit 1 + } + ;; + github-token) + ;; + *) + echo "::error::Unsupported WORKFLOW_SYNC_AUTH_MODE: ${AUTH_MODE}" + exit 1 + ;; + esac + + - name: Create LibreCode GitHub App token + if: ${{ vars.WORKFLOW_SYNC_AUTH_MODE == '' || vars.WORKFLOW_SYNC_AUTH_MODE == 'librecode-app' }} + id: librecode-app-token uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 with: app-id: ${{ vars.LIBRECODE_WORKFLOW_APP_ID }} private-key: ${{ secrets.LIBRECODE_WORKFLOW_APP_PRIVATE_KEY }} - owner: LibreCodeCoop + owner: ${{ github.repository_owner }} repositories: ${{ github.event.repository.name }} permission-contents: write permission-pull-requests: write permission-workflows: write + - name: Create consumer GitHub App token + if: ${{ vars.WORKFLOW_SYNC_AUTH_MODE == 'github-app' }} + id: consumer-app-token + uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 + with: + app-id: ${{ vars.WORKFLOW_SYNC_APP_ID }} + private-key: ${{ secrets.WORKFLOW_SYNC_APP_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + repositories: ${{ github.event.repository.name }} + permission-contents: write + permission-pull-requests: write + permission-workflows: write + + - name: Resolve workflow sync token + id: auth-token + shell: bash + env: + AUTH_MODE: ${{ vars.WORKFLOW_SYNC_AUTH_MODE || 'librecode-app' }} + LIBRECODE_APP_TOKEN: ${{ steps.librecode-app-token.outputs.token }} + CONSUMER_APP_TOKEN: ${{ steps.consumer-app-token.outputs.token }} + CONSUMER_TOKEN: ${{ secrets.WORKFLOW_SYNC_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + + case "${AUTH_MODE}" in + librecode-app) token="${LIBRECODE_APP_TOKEN}" ;; + github-app) token="${CONSUMER_APP_TOKEN}" ;; + token) token="${CONSUMER_TOKEN}" ;; + github-token) token="${GITHUB_TOKEN}" ;; + *) exit 1 ;; + esac + + [[ -n "${token}" ]] || { + echo "::error::Selected workflow sync authentication produced an empty token" + exit 1 + } + + echo "::add-mask::${token}" + echo "token=${token}" >> "${GITHUB_OUTPUT}" + - name: Checkout workflow repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -58,6 +142,12 @@ jobs: path: source repository: LibreCodeCoop/.github + - name: Record workflow catalog revision + id: catalog-revision + working-directory: source + shell: bash + run: echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" + - name: Checkout app uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -67,19 +157,20 @@ jobs: - name: Synchronize workflow templates id: sync - uses: LibreCodeCoop/github-workflows/actions/sync-workflows@5006416b915ee2d0f10f6349b4762f588a899bcd + uses: LibreCodeCoop/.github/actions/sync-workflows@492e6c7c5a9bb7642f39238583003d2cb93f3ba6 # organization helpers with: source: source/workflow-templates target: target + catalog-commit: ${{ steps.catalog-revision.outputs.sha }} - name: Create Pull Request if: ${{ steps.sync.outputs.changed == 'true' }} uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1 with: - token: ${{ steps.app-token.outputs.token }} + token: ${{ steps.auth-token.outputs.token }} commit-message: 'ci(actions): Update workflow templates from organization template repository' committer: GitHub - author: librecode-workflow-automation[bot] <331658022+librecode-workflow-automation[bot]@users.noreply.github.com> + author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> path: target signoff: true branch: 'automated/noid/${{ matrix.branches }}-update-workflows' @@ -87,7 +178,7 @@ jobs: draft: ${{ steps.sync.outputs.patch_failed == 'true' }} add-paths: .github/workflows/*.yml,.github/actions-lock.txt body: | - Automated update of all workflow templates from [LibreCodeCoop/.github](https://github.com/LibreCodeCoop/.github) + Automated update of workflow templates from [LibreCodeCoop/.github](https://github.com/LibreCodeCoop/.github) ${{ steps.sync.outputs.summary }} labels: | dependencies