-
Notifications
You must be signed in to change notification settings - Fork 0
fix(release): merge develop into main #174
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
0e17a8a
a8aebf0
99dd556
f7b22fa
566bf29
1bb25cd
dc22651
bc414d0
1fd5fa8
fd277d0
1748e31
943db14
83d82e5
3b51195
8bc6ebd
2a4a541
8d11a57
c15e1db
4a8e866
865936d
606c88a
4a70c58
bd3661f
823880d
55d36b3
bd7fc56
b4f95c9
20b73d4
36cc523
9b488d4
f908258
f260b47
7e444f0
c8b2867
0f38162
b18a15d
67ff2cc
3aa1a20
14e764a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| <table border="0" cellspacing="0" cellpadding="0"> | ||
| <tr> | ||
| <td><img src="https://github.com/LerianStudio.png" width="72" alt="Lerian" /></td> | ||
| <td><h1>backmerge-pr</h1></td> | ||
| </tr> | ||
| </table> | ||
|
|
||
| Creates a PR to backmerge a source branch into a target branch when a direct push fails. Checks for existing open PRs to avoid duplicates. | ||
|
|
||
| Typically used as a fallback in the release workflow when the `@saithodev/semantic-release-backmerge` plugin fails to push directly (non-fast-forward). | ||
|
|
||
| ## Inputs | ||
|
|
||
| | Input | Description | Required | Default | | ||
| |-------|-------------|----------|---------| | ||
| | `github-token` | GitHub token with pull-requests write permission | Yes | | | ||
| | `source-branch` | Source branch to merge from (e.g., main) | Yes | | | ||
| | `target-branch` | Target branch to merge into | No | `develop` | | ||
| | `version` | Release version for the PR title | Yes | | | ||
|
|
||
| ## Outputs | ||
|
|
||
| | Output | Description | | ||
| |--------|-------------| | ||
| | `pr-url` | URL of the created or existing PR | | ||
| | `pr-number` | Number of the created or existing PR | | ||
|
|
||
| ## Usage as composite step | ||
|
|
||
| ```yaml | ||
| - name: Create backmerge PR | ||
| uses: LerianStudio/github-actions-shared-workflows/src/config/backmerge-pr@v1.x.x | ||
| with: | ||
| github-token: ${{ secrets.GITHUB_TOKEN }} | ||
| source-branch: main | ||
| target-branch: develop | ||
| version: ${{ steps.semantic.outputs.new_release_version }} | ||
| ``` | ||
|
|
||
| ## Usage in release workflow (fallback pattern) | ||
|
|
||
| ```yaml | ||
| - name: Semantic Release | ||
| uses: cycjimmy/semantic-release-action@v6 | ||
| id: semantic | ||
| continue-on-error: true | ||
| ... | ||
|
|
||
| - name: Backmerge PR fallback | ||
| if: steps.semantic.outcome == 'failure' && steps.semantic.outputs.new_release_published == 'true' | ||
| uses: LerianStudio/github-actions-shared-workflows/src/config/backmerge-pr@v1.x.x | ||
| with: | ||
| github-token: ${{ steps.app-token.outputs.token }} | ||
| source-branch: ${{ github.ref_name }} | ||
| version: ${{ steps.semantic.outputs.new_release_version }} | ||
| ``` | ||
|
|
||
| ## Required permissions | ||
|
|
||
| ```yaml | ||
| permissions: | ||
| contents: read | ||
| pull-requests: write | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| name: Backmerge PR | ||
| description: "Creates a PR to backmerge a source branch into a target branch when a direct push fails." | ||
|
|
||
| inputs: | ||
| github-token: | ||
| description: GitHub token with pull-requests write permission | ||
| required: true | ||
| source-branch: | ||
| description: Source branch to merge from (e.g., main) | ||
| required: true | ||
| target-branch: | ||
| description: Target branch to merge into (e.g., develop) | ||
| required: false | ||
| default: develop | ||
| version: | ||
| description: Release version for the PR title (e.g., 1.20.1) | ||
| required: true | ||
|
|
||
| outputs: | ||
| pr-url: | ||
| description: URL of the created PR (empty if PR already existed or was not needed) | ||
| value: ${{ steps.create-pr.outputs.pr_url }} | ||
| pr-number: | ||
| description: Number of the created or existing PR | ||
| value: ${{ steps.create-pr.outputs.pr_number }} | ||
|
|
||
| runs: | ||
| using: composite | ||
| steps: | ||
| - name: Create backmerge PR | ||
| id: create-pr | ||
| shell: bash | ||
| env: | ||
| GH_TOKEN: ${{ inputs.github-token }} | ||
| SOURCE_BRANCH: ${{ inputs.source-branch }} | ||
| TARGET_BRANCH: ${{ inputs.target-branch }} | ||
| VERSION: ${{ inputs.version }} | ||
| run: | | ||
| # Check if a backmerge PR already exists | ||
| EXISTING_PR=$(gh pr list --base "${TARGET_BRANCH}" --head "${SOURCE_BRANCH}" --state open --json number,url --jq '.[0]') | ||
| if [ -n "$EXISTING_PR" ]; then | ||
| PR_NUM=$(echo "$EXISTING_PR" | jq -r '.number') | ||
| PR_URL=$(echo "$EXISTING_PR" | jq -r '.url') | ||
| echo "::notice::Backmerge PR #${PR_NUM} already exists: ${PR_URL}" | ||
| echo "pr_number=${PR_NUM}" >> "$GITHUB_OUTPUT" | ||
| echo "pr_url=${PR_URL}" >> "$GITHUB_OUTPUT" | ||
| exit 0 | ||
| fi | ||
|
|
||
| PR_BODY="## Description | ||
|
|
||
| Automated backmerge of release \`${VERSION}\` from \`${SOURCE_BRANCH}\` to \`${TARGET_BRANCH}\`. | ||
|
|
||
| The automatic backmerge push failed because \`${TARGET_BRANCH}\` has diverged from \`${SOURCE_BRANCH}\`. This PR needs a manual merge to resolve any conflicts. | ||
|
|
||
| > **Note:** This PR was created automatically by the release workflow." | ||
|
|
||
| PR_URL=$(gh pr create \ | ||
| --base "${TARGET_BRANCH}" \ | ||
| --head "${SOURCE_BRANCH}" \ | ||
| --title "chore(release): backmerge ${VERSION}" \ | ||
| --body "${PR_BODY}") | ||
|
|
||
| PR_NUM=$(echo "$PR_URL" | grep -oE '[0-9]+$') | ||
| echo "pr_number=${PR_NUM}" >> "$GITHUB_OUTPUT" | ||
| echo "pr_url=${PR_URL}" >> "$GITHUB_OUTPUT" | ||
| echo "::notice::Backmerge push failed — created PR #${PR_NUM}: ${PR_URL}" | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,60 +1,14 @@ | ||||||
| name: Validate PR Description | ||||||
| description: "Validates that the PR description has real content beyond template boilerplate." | ||||||
|
|
||||||
| inputs: | ||||||
| min-length: | ||||||
| description: Minimum content length in characters (after stripping template boilerplate) | ||||||
| required: false | ||||||
| default: "30" | ||||||
| description: "Checks that the PR description is not empty." | ||||||
|
|
||||||
| runs: | ||||||
| using: composite | ||||||
| steps: | ||||||
| - name: Validate PR description | ||||||
| - name: Check description | ||||||
| uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix yamllint spacing warning. Pipeline reports: "too few spaces before comment: expected 2". Add a space before the version comment. Proposed fix- uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8📝 Committable suggestion
Suggested change
🧰 Tools🪛 GitHub Actions: Self — PR Validation[warning] 8-8: Yamllint warning: too few spaces before comment: expected 2 (comments) 🤖 Prompt for AI Agents |
||||||
| env: | ||||||
| MIN_LENGTH: ${{ inputs.min-length }} | ||||||
| with: | ||||||
| script: | | ||||||
| const body = context.payload.pull_request.body || ''; | ||||||
| const minLength = parseInt(process.env.MIN_LENGTH, 10); | ||||||
| if (isNaN(minLength) || minLength <= 0) { | ||||||
| core.setFailed(`Invalid min-length input: '${process.env.MIN_LENGTH}'`); | ||||||
| return; | ||||||
| } | ||||||
| const errors = []; | ||||||
| const warnings = []; | ||||||
|
|
||||||
| // --- Extract content under "## Description" heading --- | ||||||
| const descriptionMatch = body.match(/## Description\s*\n([\s\S]*?)(?=\n## |\n---\s*$|$)/); | ||||||
| const descriptionContent = descriptionMatch ? descriptionMatch[1].trim() : ''; | ||||||
|
|
||||||
| // Strip HTML comments <!-- ... --> | ||||||
| const cleaned = descriptionContent.replace(/<!--[\s\S]*?-->/g, '').trim(); | ||||||
|
|
||||||
| if (cleaned.length === 0) { | ||||||
| errors.push('The "Description" section is empty. Please summarize what this PR does and why.'); | ||||||
| } else if (cleaned.length < minLength) { | ||||||
| errors.push(`The "Description" section is too short (${cleaned.length} chars, minimum ${minLength}). Please provide more detail.`); | ||||||
| } | ||||||
|
|
||||||
| // --- Check that at least one "Type of Change" checkbox is checked --- | ||||||
| const typeMatch = body.match(/## Type of Change\s*\n([\s\S]*?)(?=\n## |$)/); | ||||||
| if (typeMatch) { | ||||||
| const typeSection = typeMatch[1]; | ||||||
| const checked = typeSection.match(/- \[x\]/gi); | ||||||
| if (!checked) { | ||||||
| errors.push('No "Type of Change" checkbox is checked. Please mark at least one.'); | ||||||
| } | ||||||
| } else { | ||||||
| errors.push('Missing "Type of Change" section. Please use the PR template.'); | ||||||
| } | ||||||
|
|
||||||
| // --- Report --- | ||||||
| for (const w of warnings) { | ||||||
| core.warning(w); | ||||||
| } | ||||||
|
|
||||||
| if (errors.length > 0) { | ||||||
| core.setFailed(errors.join('\n')); | ||||||
| const body = (context.payload.pull_request.body || '').trim(); | ||||||
| if (body.length === 0) { | ||||||
| core.setFailed('PR description is empty. Please provide a description.'); | ||||||
| } | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Output description contradicts implementation.
Line 21 states
pr-urlis "empty if PR already existed" but the implementation at lines 43-46 setspr_urlfor existing PRs. Either update the description or the behavior.Suggested fix
🤖 Prompt for AI Agents