From 0198fcfca31ad650b4d900e2b378fc31805ad575 Mon Sep 17 00:00:00 2001 From: Vitor Mattos Date: Tue, 22 Sep 2026 00:16:10 -0300 Subject: [PATCH 1/2] test: cover pull-request nightly notes Signed-off-by: Vitor Mattos --- tests/test_nightly_release_template.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/test_nightly_release_template.py b/tests/test_nightly_release_template.py index 021397f..7ef4701 100644 --- a/tests/test_nightly_release_template.py +++ b/tests/test_nightly_release_template.py @@ -54,11 +54,19 @@ def test_release_notes_do_not_emit_literal_newline_escapes(self) -> None: self.assertNotIn(".\\\\\\\\n'", content) + def test_release_notes_prefer_pull_requests_with_commit_fallback(self) -> None: + content = TEMPLATE.read_text(encoding="utf-8") + + self.assertIn('commits/${sha}/pulls', content) + self.assertIn('unique_by(.number)', content) + self.assertIn('([#%s](%s))', content) + self.assertIn("git show -s --format='%s'", content) + def test_checkout_credentials_are_not_persisted(self) -> None: content = TEMPLATE.read_text(encoding="utf-8") self.assertNotIn("persist-credentials: true", content) - self.assertIn("permissions:\n contents: write", content) + self.assertIn("permissions:\n contents: write\n pull-requests: read", content) self.assertNotIn("actions: write", content) def test_concurrency_only_cancels_runs_for_the_same_branch(self) -> None: From 71ab0beea4d5138b2005666a22f933cffc251c99 Mon Sep 17 00:00:00 2001 From: Vitor Mattos Date: Tue, 22 Sep 2026 00:20:46 -0300 Subject: [PATCH 2/2] fix: render nightly notes from pull requests Signed-off-by: Vitor Mattos --- workflow-templates/nightly-release.yml | 113 ++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 4 deletions(-) diff --git a/workflow-templates/nightly-release.yml b/workflow-templates/nightly-release.yml index 81f905e..6818195 100644 --- a/workflow-templates/nightly-release.yml +++ b/workflow-templates/nightly-release.yml @@ -16,6 +16,7 @@ on: permissions: contents: write + pull-requests: read concurrency: group: nightly-release-${{ github.repository }}-${{ github.ref_name }} @@ -242,12 +243,116 @@ jobs: env: NIGHTLY_BRANCH: ${{ steps.nightly.outputs.branch }} run: | - last_tag="$(git tag --list --sort=-version:refname | grep -v '^nightly$' | head -1 || true)" + last_tag="$(git tag --list --sort=-version:refname | grep -v '^nightly echo + echo "---" + printf 'Generated from commit `%s`.\n' "${GITHUB_SHA:0:7}" + } > release-notes.md + + - name: Create or update GitHub release + shell: bash + env: + GH_TOKEN: ${{ github.token }} + NIGHTLY_BRANCH: ${{ steps.nightly.outputs.branch }} + run: | + title="Nightly ${APP_VERSION} (${NIGHTLY_BRANCH})" + notes="${APP_NAME}/release-notes.md" + if gh release view nightly --repo "${GITHUB_REPOSITORY}" >/dev/null 2>&1; then + gh release edit nightly --repo "${GITHUB_REPOSITORY}" --title "${title}" --notes-file "${notes}" --prerelease + else + gh release create nightly --repo "${GITHUB_REPOSITORY}" --title "${title}" --notes-file "${notes}" --prerelease + fi + + - name: Attach tarball to GitHub release + id: attach-to-release + uses: svenstaro/upload-release-action@29e53e917877a24fad85510ded594ab3c9ca12de # v2.11.5 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: ${{ env.APP_NAME }}/build/artifacts/${{ env.APP_NAME }}.tar.gz + asset_name: ${{ env.APP_NAME }}-nightly.tar.gz + tag: nightly + overwrite: true + + - name: Upload nightly to Nextcloud App Store + uses: nextcloud-libraries/nextcloud-appstore-push-action@a011fe619bcf6e77ddebc96f9908e1af4071b9c1 # v1.0.3 + with: + app_name: ${{ env.APP_NAME }} + appstore_token: ${{ secrets.APPSTORE_TOKEN }} + download_url: ${{ steps.attach-to-release.outputs.browser_download_url }} + app_private_key: ${{ secrets.APP_PRIVATE_KEY }} + nightly: true + | head -1 || true)" if [ -n "${last_tag}" ]; then - commits="$(git log "${last_tag}..HEAD" --pretty=format:'- %s (%h)' --no-merges)" + mapfile -t commit_shas < <(git rev-list --reverse "${last_tag}..HEAD") + else + mapfile -t commit_shas < <(git rev-list --reverse --max-count=10 HEAD) + fi + + : > nightly-changes.md + declare -A seen_prs=() + for sha in "${commit_shas[@]}"; do + pr_json="$(gh api \ + -H 'Accept: application/vnd.github+json' \ + "repos/${GITHUB_REPOSITORY}/commits/${sha}/pulls" 2>/dev/null || printf '[]')" + pr_line="$(jq -r --arg branch "${NIGHTLY_BRANCH}" ' + map(select(.merged_at != null)) + | (map(select(.base.ref == $branch)) + .) + | unique_by(.number) + | first + | if . == null then empty + else "\(.number)\t\(.title)\t\(.html_url)" + end + ' <<<"${pr_json}")" + + if [ -n "${pr_line}" ]; then + IFS= echo + echo "---" + printf 'Generated from commit `%s`.\n' "${GITHUB_SHA:0:7}" + } > release-notes.md + + - name: Create or update GitHub release + shell: bash + env: + GH_TOKEN: ${{ github.token }} + NIGHTLY_BRANCH: ${{ steps.nightly.outputs.branch }} + run: | + title="Nightly ${APP_VERSION} (${NIGHTLY_BRANCH})" + notes="${APP_NAME}/release-notes.md" + if gh release view nightly --repo "${GITHUB_REPOSITORY}" >/dev/null 2>&1; then + gh release edit nightly --repo "${GITHUB_REPOSITORY}" --title "${title}" --notes-file "${notes}" --prerelease else - commits="$(git log -10 --pretty=format:'- %s (%h)' --no-merges)" + gh release create nightly --repo "${GITHUB_REPOSITORY}" --title "${title}" --notes-file "${notes}" --prerelease fi + + - name: Attach tarball to GitHub release + id: attach-to-release + uses: svenstaro/upload-release-action@29e53e917877a24fad85510ded594ab3c9ca12de # v2.11.5 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: ${{ env.APP_NAME }}/build/artifacts/${{ env.APP_NAME }}.tar.gz + asset_name: ${{ env.APP_NAME }}-nightly.tar.gz + tag: nightly + overwrite: true + + - name: Upload nightly to Nextcloud App Store + uses: nextcloud-libraries/nextcloud-appstore-push-action@a011fe619bcf6e77ddebc96f9908e1af4071b9c1 # v1.0.3 + with: + app_name: ${{ env.APP_NAME }} + appstore_token: ${{ secrets.APPSTORE_TOKEN }} + download_url: ${{ steps.attach-to-release.outputs.browser_download_url }} + app_private_key: ${{ secrets.APP_PRIVATE_KEY }} + nightly: true +\t' read -r pr_number pr_title pr_url <<<"${pr_line}" + if [ -z "${seen_prs[${pr_number}]+x}" ]; then + printf -- '- %s ([#%s](%s))\n' "${pr_title}" "${pr_number}" "${pr_url}" >> nightly-changes.md + seen_prs["${pr_number}"]=1 + fi + continue + fi + + subject="$(git show -s --format='%s' "${sha}")" + printf -- '- %s (`%s`)\n' "${subject}" "${sha:0:7}" >> nightly-changes.md + done + { echo "## 🌙 Nightly Build - ${APP_VERSION}" echo @@ -257,7 +362,7 @@ jobs: echo echo "### Recent Changes" echo - printf '%s\n' "${commits}" + cat nightly-changes.md echo echo "---" printf 'Generated from commit `%s`.\n' "${GITHUB_SHA:0:7}"