Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
174 changes: 174 additions & 0 deletions .github/workflows/backport.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ on:
permissions:
contents: read
pull-requests: write
statuses: write
actions: read

jobs:
get-branches:
Expand Down Expand Up @@ -168,3 +170,175 @@ jobs:
slack_webhook_url: ${{ secrets.EXTERNAL_SLACK_DETECTION_RULES_URL }}
status: failure
if: failure()

post-pending:
if: |
github.event.pull_request.merged == true
&& contains(github.event.pull_request.labels.*.name, 'backport: auto')
&& (
(github.event.action == 'labeled' && github.event.label.name == 'backport: auto')
|| (github.event.action == 'closed')
)
runs-on: ubuntu-latest
steps:
- name: Mark release-line-caught-up pending
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
env:
MERGE_SHA: ${{ github.event.pull_request.merge_commit_sha }}
STATUS_CONTEXT: release-line-caught-up
with:
script: |
await github.rest.repos.createCommitStatus({
owner: context.repo.owner,
repo: context.repo.repo,
sha: process.env.MERGE_SHA,
state: 'pending',
context: process.env.STATUS_CONTEXT,
description: 'Waiting for auto-backports and release-branch Unit Tests',
target_url: `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`,
});

mark-caught-up-skip:
if: |
github.event.pull_request.merged == true
&& contains(github.event.pull_request.labels.*.name, 'backport: skip')
&& github.event.action == 'closed'
runs-on: ubuntu-latest
steps:
- name: Mark release-line-caught-up success (backport skipped)
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
env:
MERGE_SHA: ${{ github.event.pull_request.merge_commit_sha }}
STATUS_CONTEXT: release-line-caught-up
with:
script: |
await github.rest.repos.createCommitStatus({
owner: context.repo.owner,
repo: context.repo.repo,
sha: process.env.MERGE_SHA,
state: 'success',
context: process.env.STATUS_CONTEXT,
description: 'backport: skip; no release-line wait required',
target_url: `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`,
});

mark-caught-up:
needs: [get-branches, commit]
if: |
always()
&& github.event.pull_request.merged == true
&& contains(github.event.pull_request.labels.*.name, 'backport: auto')
&& (
(github.event.action == 'labeled' && github.event.label.name == 'backport: auto')
|| (github.event.action == 'closed')
)
&& needs.commit.result != 'skipped'
runs-on: ubuntu-latest
timeout-minutes: 24
steps:
- name: Wait for tip Unit Tests and mark release-line-caught-up
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
env:
BRANCHES: ${{ toJSON(fromJSON(needs.get-branches.outputs.branches)) }}
COMMIT_RESULT: ${{ needs.commit.result }}
MERGE_SHA: ${{ github.event.pull_request.merge_commit_sha }}
STATUS_CONTEXT: release-line-caught-up
WORKFLOW_FILE: pythonpackage.yml
WAIT_SECONDS: "1320"
POLL_SECONDS: "15"
with:
script: |
const { owner, repo } = context.repo;
const contextName = process.env.STATUS_CONTEXT;
const mergeSha = process.env.MERGE_SHA;
const targetUrl = `${context.serverUrl}/${owner}/${repo}/actions/runs/${context.runId}`;

async function postStatus(state, description) {
await github.rest.repos.createCommitStatus({
owner,
repo,
sha: mergeSha,
state,
context: contextName,
description: description.slice(0, 140),
target_url: targetUrl,
});
}

if (process.env.COMMIT_RESULT !== 'success') {
const message = `Auto-backport commit job ${process.env.COMMIT_RESULT}`;
await postStatus('failure', message);
core.setFailed(message);
return;
}

const branches = JSON.parse(process.env.BRANCHES);
const workflowFile = process.env.WORKFLOW_FILE;
const waitMs = Number(process.env.WAIT_SECONDS) * 1000;
const pollMs = Number(process.env.POLL_SECONDS) * 1000;
const deadline = Date.now() + waitMs;

async function sleep() {
await new Promise((resolve) => setTimeout(resolve, pollMs));
}

async function unitTestRuns(sha) {
const { data } = await github.rest.actions.listWorkflowRuns({
owner,
repo,
workflow_id: workflowFile,
head_sha: sha,
per_page: 10,
});
return data.workflow_runs || [];
}

function classifyRuns(runs) {
if (runs.some((run) => run.status === 'completed' && run.conclusion === 'success')) {
return 'success';
}
if (runs.some((run) => run.status === 'in_progress' || run.status === 'queued' || run.status === 'waiting' || run.status === 'pending')) {
return 'pending';
}
if (runs.some((run) => run.status === 'completed')) {
const failed = runs.find((run) => run.status === 'completed');
return `failed:${failed.conclusion}`;
}
return 'missing';
}

while (true) {
const results = [];
for (const branch of branches) {
const { data } = await github.rest.repos.getBranch({ owner, repo, branch });
const sha = data.commit.sha;
const result = classifyRuns(await unitTestRuns(sha));
results.push({ branch, sha, result });
}

const summary = results
.map((item) => `${item.branch} @ ${item.sha.slice(0, 7)}: ${item.result}`)
.join('\n');
core.info(summary);

if (results.every((item) => item.result === 'success')) {
await postStatus('success', 'All release targets backported; tip Unit Tests passed');
return;
}

const failed = results.find((item) => item.result.startsWith('failed:'));
if (failed) {
const message = `${failed.branch} Unit Tests ${failed.result}`;
await postStatus('failure', message);
core.setFailed(`${message}\n${summary}`);
return;
}

if (Date.now() >= deadline) {
const message = `Timed out waiting for release-branch Unit Tests`;
await postStatus('failure', message);
core.setFailed(`${message}\n${summary}`);
return;
}
await sleep();
}
40 changes: 0 additions & 40 deletions .github/workflows/branch-status-checks.yml

This file was deleted.

2 changes: 2 additions & 0 deletions .github/workflows/code-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ on:
- 'hunting/**/*.py'
- 'tests/**/*.py'
- 'lib/**/*.py'
merge_group:
branches: [ main ]

permissions:
contents: read
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/esql-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ name: ES|QL Validation
on:
pull_request:
branches: [ "*" ]
merge_group:
branches: [ main ]

permissions:
contents: read
Expand Down Expand Up @@ -29,7 +31,8 @@ jobs:
exit 0
fi

MODIFIED_FILES=$(git diff --name-only --diff-filter=AM HEAD~1 | grep '^rules/.*\.toml$' || true)
BASE_SHA="${{ github.event_name == 'merge_group' && github.event.merge_group.base_sha || github.event.pull_request.base.sha }}"
MODIFIED_FILES=$(git diff --name-only --diff-filter=AM "$BASE_SHA" HEAD | grep '^rules/.*\.toml$' || true)
if [ -z "$MODIFIED_FILES" ]; then
echo "No modified or new .toml files found. Skipping workflow."
echo "run_esql=false" >> $GITHUB_ENV
Expand Down
89 changes: 0 additions & 89 deletions .github/workflows/manual-backport.yml

This file was deleted.

2 changes: 2 additions & 0 deletions .github/workflows/pythonpackage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ on:
branches: [ "main", "7.*", "8.*", "9.*" ]
pull_request:
branches: [ "*" ]
merge_group:
branches: [ main ]

permissions:
contents: read
Expand Down
Loading
Loading