diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4f5e103d..a0d205a4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -113,7 +113,7 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | base_ref="origin/${GITHUB_BASE_REF:-main}" - plan_files=$(git log "$base_ref"...HEAD \ + plan_files=$(git log "$base_ref"..HEAD \ --diff-filter=A --name-only --pretty=format: \ -- 'docs/plans/*.md' | sed '/^$/d') @@ -164,7 +164,7 @@ jobs: fi base_ref="origin/${GITHUB_BASE_REF:-main}" - output=$(git log "$base_ref"...HEAD --name-status --pretty=format: -- CHANGELOG.md | sed '/^$/d') + output=$(git log "$base_ref"..HEAD --name-status --pretty=format: -- CHANGELOG.md | sed '/^$/d') if [ -n "$output" ]; then echo "::error::CHANGELOG.md is release-workflow-owned and must not appear in PR branch history" diff --git a/.github/workflows/promote-next-to-main.yml b/.github/workflows/promote-next-to-main.yml index b2c1b712..d14cf935 100644 --- a/.github/workflows/promote-next-to-main.yml +++ b/.github/workflows/promote-next-to-main.yml @@ -31,8 +31,17 @@ jobs: - name: Fetch main and next refs run: git fetch origin main next + - name: Generate linearis-bot app token + id: app-token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.RELEASE_APP_ID }} + private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }} + - name: Build PR metadata id: meta + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} shell: bash run: | set -euo pipefail @@ -40,10 +49,43 @@ jobs: version=$(node -p "require('./package.json').version.replace(/-next\\.\\d+$/, '')") title="release ${version} to stable channel" compare_url="https://github.com/${GITHUB_REPOSITORY}/compare/main...next" + owner="${GITHUB_REPOSITORY%/*}" + repo="${GITHUB_REPOSITORY#*/}" + + mapfile -t commit_shas < <(git rev-list --no-merges origin/main..origin/next) + + declare -A seen_prs=() + included_prs="" + + for sha in "${commit_shas[@]}"; do + response=$(gh api graphql \ + -f owner="$owner" \ + -f repo="$repo" \ + -f oid="$sha" \ + -f query='query($owner: String!, $repo: String!, $oid: GitObjectID!) { repository(owner: $owner, name: $repo) { object(oid: $oid) { ... on Commit { associatedPullRequests(first: 10) { nodes { number title url author { login } } } } } } }' \ + 2>/dev/null || true) + + if [ -z "$response" ]; then + continue + fi + + while IFS=$'\t' read -r number pr_title pr_url pr_author; do + if [ -z "$number" ] || [ -n "${seen_prs[$number]:-}" ]; then + continue + fi + + seen_prs[$number]=1 + + if [ -z "$pr_author" ] || [ "$pr_author" = "null" ]; then + pr_author="unknown" + fi + + included_prs+="- [#${number}](${pr_url}) ${pr_title} by @${pr_author} — thanks @${pr_author}!\n" + done < <(printf '%s' "$response" | jq -r '.data.repository.object.associatedPullRequests.nodes[]? | [.number, .title, .url, .author.login] | @tsv') + done - commits=$(git log --no-merges --pretty='- %h %s' origin/main..origin/next | head -n 200) - if [ -z "$commits" ]; then - commits="- (no new commits; branches currently aligned)" + if [ -z "$included_prs" ]; then + included_prs="- (no included pull requests found; branches may be aligned)" fi { @@ -57,8 +99,8 @@ jobs: echo "## Target stable version" echo "\\`$version\\`" echo - echo "## Included commits (next ahead of main)" - echo "$commits" + echo "## Included pull requests (next ahead of main)" + printf '%b\n' "$included_prs" echo echo "## Compare" echo "$compare_url" @@ -71,7 +113,7 @@ jobs: - name: Upsert promotion PR env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ steps.app-token.outputs.token }} shell: bash run: | set -euo pipefail diff --git a/.releaserc.cjs b/.releaserc.cjs index 39398d88..bd128607 100644 --- a/.releaserc.cjs +++ b/.releaserc.cjs @@ -15,7 +15,10 @@ module.exports = { ["@semantic-release/npm", { npmPublish: false, pkgRoot: "." }], [ "@semantic-release/exec", - { publishCmd: "npx clean-publish --access public -- --provenance" }, + { + publishCmd: + 'npx clean-publish --access public --tag $( [ "$GITHUB_REF_NAME" = "next" ] && echo next || echo latest ) -- --provenance', + }, ], ["@semantic-release/github", { successComment: false, failComment: false }], [