Skip to content
Merged
68 changes: 68 additions & 0 deletions .github/workflows/backport.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: Backport

on:
pull_request_target:
types: [closed, labeled]

permissions:
contents: write
pull-requests: write

jobs:
backport:
name: Backport PR
if: >
github.event.pull_request.merged == true
&& contains(join(github.event.pull_request.labels.*.name, ','), 'backport-to-')
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}

- name: Create backport PR(s)
uses: korthout/backport-action@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
label_pattern: "^backport-to-(.+)$"
merge_commits: "skip"
pull_title: "[Backport ${target_branch}] ${pull_title}"
pull_description: |
Backport of #${pull_number} to `${target_branch}`.

---

${pull_description}
copy_requested_reviewers: true
copy_assignees: true
copy_labels_pattern: "^(?!backport-to-)"
auto_merge_enabled: ${{ contains(join(github.event.pull_request.labels.*.name, ','), 'backport-auto-merge') }}

- name: Report backport status
if: failure()
uses: actions/github-script@v7
with:
script: |
const { owner, repo } = context.repo;
const pullNumber = context.payload.pull_request.number;

await github.rest.issues.createComment({
owner,
repo,
issue_number: pullNumber,
body: [
"⚠️ **Backport failed!**",
"",
"Automatic backport could not be completed. This is usually caused by cherry-pick conflicts or a missing target branch.",
"",
"Manual backport example:",
"",
"```bash",
"git checkout <target-branch>",
`git cherry-pick -x ${context.payload.pull_request.merge_commit_sha}`,
"```",
].join("\\n"),
});
178 changes: 178 additions & 0 deletions .github/workflows/tag-and-promote-from-pr-label.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
name: Tag and promote from PR label

on:
pull_request_target:
types:
- closed
- labeled

permissions:
contents: write
pull-requests: read

jobs:
tag-and-promote:
if: >
github.event.pull_request.merged == true &&
(
github.event.action == 'closed' ||
(
github.event.action == 'labeled' &&
startsWith(github.event.label.name, 'promote/')
)
)
runs-on: ubuntu-latest

steps:
- name: Determine target branch from PR labels
id: target
uses: actions/github-script@v8
with:
script: |
const labels = context.payload.pull_request.labels.map(label => label.name);

const mapping = {
"promote/version-15": "version-15",
"promote/version-16": "version-16",
"promote/production": "production"
};

const matchedLabels = labels.filter(label => mapping[label]);

if (matchedLabels.length === 0) {
core.info(
`No promote target label found. Skipping promotion. Add one of: ${Object.keys(mapping).join(", ")}`
);
core.setOutput("should_promote", "false");
return;
}

if (matchedLabels.length > 1) {
core.setFailed(
`Multiple promote target labels found: ${matchedLabels.join(", ")}. Keep only one.`
);
return;
}

const matchedLabel = matchedLabels[0];

core.setOutput("should_promote", "true");
core.setOutput("target_branch", mapping[matchedLabel]);
core.setOutput("matched_label", matchedLabel);

- name: Checkout merged commit
if: steps.target.outputs.should_promote == 'true'
uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.merge_commit_sha }}
fetch-depth: 0

- name: Read version from av_tools.__version__
if: steps.target.outputs.should_promote == 'true'
id: version
shell: bash
run: |
VERSION=$(python - <<'PY'
import re
from pathlib import Path

init_file = Path("av_tools/__init__.py")
content = init_file.read_text()

match = re.search(r'^__version__\s*=\s*["\']([^"\']+)["\']', content, re.M)

if not match:
raise SystemExit("Could not find __version__ in av_tools/__init__.py")

print(match.group(1))
PY
)

echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "tag=v$VERSION" >> "$GITHUB_OUTPUT"

- name: Configure git user
if: steps.target.outputs.should_promote == 'true'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- name: Create and push version tag
if: steps.target.outputs.should_promote == 'true'
shell: bash
run: |
git fetch --tags

TAG="${{ steps.version.outputs.tag }}"
CURRENT_COMMIT="$(git rev-parse HEAD)"

if git rev-parse "$TAG" >/dev/null 2>&1; then
TAG_COMMIT="$(git rev-list -n 1 "$TAG")"

if [ "$TAG_COMMIT" != "$CURRENT_COMMIT" ]; then
echo "Tag $TAG already exists but points to $TAG_COMMIT, not current merged commit $CURRENT_COMMIT."
exit 1
fi

echo "Tag $TAG already exists and points to the current merged commit. Skipping tag creation."
exit 0
fi

git tag -a "$TAG" -m "Release $TAG"
git push origin "$TAG"

- name: Create GitHub release with generated title and notes
if: steps.target.outputs.should_promote == 'true'
uses: actions/github-script@v8
env:
TAG_NAME: ${{ steps.version.outputs.tag }}
TARGET_COMMITISH: ${{ github.event.pull_request.merge_commit_sha }}
with:
script: |
const tagName = process.env.TAG_NAME;
const targetCommitish = process.env.TARGET_COMMITISH;
const { owner, repo } = context.repo;

try {
const existingRelease = await github.rest.repos.getReleaseByTag({
owner,
repo,
tag: tagName
});

core.info(
`Release already exists for ${tagName}: ${existingRelease.data.html_url}. Skipping release creation.`
);
return;
} catch (error) {
if (error.status !== 404) {
throw error;
}
}

const generatedNotes = await github.rest.repos.generateReleaseNotes({
owner,
repo,
tag_name: tagName,
target_commitish: targetCommitish,
previous_tag_name: undefined
});

const release = await github.rest.repos.createRelease({
owner,
repo,
tag_name: tagName,
target_commitish: targetCommitish,
name: generatedNotes.data.name,
body: generatedNotes.data.body,
draft: false,
prerelease: false
});

core.info(`Created release: ${release.data.html_url}`);

- name: Promote merged commit to target branch
if: steps.target.outputs.should_promote == 'true'
shell: bash
run: |
git push origin HEAD:${{ steps.target.outputs.target_branch }}
2 changes: 1 addition & 1 deletion av_tools/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.0.1"
__version__ = "15.2.0"
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ frappe.ui.form.on('Special Closing Balance', {

frm.set_query("item_code", "closing_balance_details", function(doc, cdt, cdn) {
return {
query: "erpnext.controllers.queries.item_query",
query: "av_tools.av_tools_hooks.item_search.item_query",
filters:{
"is_stock_item": 1
}
Expand Down
Loading
Loading