diff --git a/tests/test_nightly_release_template.py b/tests/test_nightly_release_template.py index 7ef4701..2841ad4 100644 --- a/tests/test_nightly_release_template.py +++ b/tests/test_nightly_release_template.py @@ -54,13 +54,23 @@ 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: + def test_release_notes_use_shared_pull_request_action(self) -> None: content = TEMPLATE.read_text(encoding="utf-8") + sha = "db491a51227ff4fd76b35b7a24ab7718aab6cbee" - 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) + self.assertIn( + f"actions/release-notes-from-pull-requests@{sha}", + content, + ) + self.assertIn("from-ref: ${{ steps.release-note-range.outputs.from-ref }}", content) + self.assertIn("branch: ${{ steps.nightly.outputs.branch }}", content) + self.assertIn( + "CHANGES_FILE: ${{ steps.release-note-changes.outputs.changes-file }}", + content, + ) + self.assertNotIn("declare -A seen_prs", content) + self.assertNotIn('commits/${sha}/pulls', content) + self.assertNotIn("unique_by(.number)", content) def test_checkout_credentials_are_not_persisted(self) -> None: content = TEMPLATE.read_text(encoding="utf-8") diff --git a/workflow-templates/nightly-release.yml b/workflow-templates/nightly-release.yml index eee1c2b..b5f1b44 100644 --- a/workflow-templates/nightly-release.yml +++ b/workflow-templates/nightly-release.yml @@ -237,49 +237,66 @@ jobs: gh api --method POST "repos/${GITHUB_REPOSITORY}/git/refs" -f ref='refs/tags/nightly' -f sha="${GITHUB_SHA}" >/dev/null fi - - name: Build nightly release notes + - name: Resolve nightly release note range + id: release-note-range working-directory: ${{ env.APP_NAME }} + shell: bash + run: | + last_tag="$(git tag --list --sort=-version:refname | grep -v '^nightly + - name: Create or update GitHub release shell: bash env: - NIGHTLY_BRANCH: ${{ steps.nightly.outputs.branch }} GH_TOKEN: ${{ github.token }} + NIGHTLY_BRANCH: ${{ steps.nightly.outputs.branch }} run: | - last_tag="$(git tag --list --sort=-version:refname | grep -v '^nightly$' | head -1 || true)" - if [ -n "${last_tag}" ]; then - mapfile -t commit_shas < <(git rev-list --reverse "${last_tag}..HEAD") + 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 - mapfile -t commit_shas < <(git rev-list --reverse --max-count=10 HEAD) + gh release create nightly --repo "${GITHUB_REPOSITORY}" --title "${title}" --notes-file "${notes}" --prerelease 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=$'\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 + - 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)" + echo "from-ref=${last_tag}" >> "${GITHUB_OUTPUT}" + - name: Build nightly change list + id: release-note-changes + uses: LibreCodeCoop/github-workflows/actions/release-notes-from-pull-requests@db491a51227ff4fd76b35b7a24ab7718aab6cbee + with: + github-token: ${{ github.token }} + repository: ${{ github.repository }} + branch: ${{ steps.nightly.outputs.branch }} + working-directory: ${{ env.APP_NAME }} + from-ref: ${{ steps.release-note-range.outputs.from-ref }} + to-ref: HEAD + fallback-limit: '10' + + - name: Build nightly release notes + working-directory: ${{ env.APP_NAME }} + shell: bash + env: + NIGHTLY_BRANCH: ${{ steps.nightly.outputs.branch }} + CHANGES_FILE: ${{ steps.release-note-changes.outputs.changes-file }} + run: | { echo "## 🌙 Nightly Build - ${APP_VERSION}" echo @@ -289,7 +306,7 @@ jobs: echo echo "### Recent Changes" echo - cat nightly-changes.md + cat "${CHANGES_FILE}" echo echo "---" printf 'Generated from commit `%s`.\n' "${GITHUB_SHA:0:7}"