Skip to content

ci: add Copilot automation + security workflows (14 workflows) - #32

Open
m0nk1111 wants to merge 1 commit into
masterfrom
feat/copilot-workflows
Open

ci: add Copilot automation + security workflows (14 workflows)#32
m0nk1111 wants to merge 1 commit into
masterfrom
feat/copilot-workflows

Conversation

@m0nk1111

Copy link
Copy Markdown
Collaborator

Copilot Automation + Security Workflows

Adapted from m0nklabs/cryptotrader workflow suite for the Mycodo fork.

What's included (14 workflows)

Copilot SWE Agent Automation (10)

Workflow Purpose
auto-approve-workflows Bypass first-time contributor approval for Copilot PRs (runs every 2 min)
copilot-auto-assign Auto-assign Copilot to highest priority open issue (runs every 5 min)
copilot-branch-ci Lightweight lint CI for copilot/** branches (ruff + syntax check)
copilot-autofix Auto-fix style issues when branch CI fails
copilot-ci-feedback Notify Copilot of main CI failures with fix requests (loop protection: 3 max)
copilot-ready-pr Mark draft PRs ready for review after CI passes (1h cooldown)
copilot-rebase Keep Copilot branches up-to-date with master (manual dispatch)
copilot-request-review Request Copilot Reviewer after agent finishes work
copilot-auto-review-llm LLM-powered triage of Copilot Reviewer feedback via Guardian
copilot-review-feedback Forward review suggestions summary to PR comments

General Automation (2)

Workflow Purpose
automation-cleanup-pr-body Clean HTML comments and empty sections from PR bodies
automation-stale Mark/close stale issues (60d) and PRs (30d)

Security (2)

Workflow Purpose
security-codeql Python CodeQL analysis (weekly + on push/PR to master)
security-gitleaks Secret scanning with Gitleaks (weekly + on push/PR to master)

What's NOT included (and why)

  • ci.ymlmain.yml already handles full Mycodo CI
  • automation-release.yml — fork doesn't do releases
  • automation-label-issues.yml — would need full label remap for Mycodo domain
  • custom-agent.yml — requires scripts/custom_agent.py which doesn't exist yet

Adaptations from cryptotrader

  • Runner: [self-hosted, Linux] (no org label since this is a personal repo)
  • Python version: 3.11 (Mycodo's version, not 3.12)
  • Workflow triggers: "CI""Mycodo" (matches main.yml name)
  • Removed run-header composite action references (doesn't exist in this repo)
  • Removed database setup (no PostgreSQL needed)
  • Removed EPIC priority map (no EPICs on this fork)
  • Removed exchange-specific secrets (BITFINEX_*, OPENROUTER_*)
  • Simplified Copilot Branch CI to lightweight lint only (full CI is too heavy for rapid iteration)
  • CodeQL: Python only (no JavaScript)
  • Alert cc: @m0nk111 (not @m0nk1111)

Required Secrets

Secret Purpose
GH_PAT Personal Access Token with repo, workflow, read:org scopes

Required Setup

  1. Register self-hosted runner for m0nk111/Mycodo (Settings → Actions → Runners → New self-hosted runner)
    • Labels: self-hosted, Linux
    • Same machine as cryptotrader runner (192.168.1.26)
  2. Add GH_PAT secret (Settings → Secrets → Actions → New repository secret)
  3. Enable Copilot SWE agent if not already enabled

Copilot Agent Loop (how it works)

Issue created → auto-assign picks it up → Copilot creates branch + PR
→ copilot-branch-ci runs lint → autofix if needed → request-review
→ auto-review-llm triages feedback → posts fix requests if needed
→ Copilot fixes → CI re-runs → ready-pr marks it ready → human review

Adapted from m0nklabs/cryptotrader workflow suite:

Copilot SWE Agent automation:
- auto-approve-workflows: bypass first-time contributor approval
- copilot-auto-assign: auto-assign Copilot to priority issues
- copilot-branch-ci: lightweight lint CI for copilot/** branches
- copilot-autofix: auto-fix style issues on CI failure
- copilot-ci-feedback: notify Copilot of CI failures with fix requests
- copilot-ready-pr: mark draft PRs ready after CI passes
- copilot-rebase: keep Copilot branches up-to-date with master
- copilot-request-review: request Copilot Reviewer after agent finishes
- copilot-auto-review-llm: LLM triage of Copilot Reviewer feedback
- copilot-review-feedback: forward review suggestions summary

General automation:
- automation-cleanup-pr-body: clean HTML comments and empty sections
- automation-stale: mark/close stale issues and PRs

Security:
- security-codeql: Python CodeQL analysis
- security-gitleaks: secret scanning with Gitleaks

All workflows use [self-hosted, Linux] runners.
Required secrets: GH_PAT, APP_ID, APP_PRIVATE_KEY
Copilot AI review requested due to automatic review settings February 23, 2026 23:36

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a suite of GitHub Actions workflows to automate Copilot SWE agent lifecycle (assignment → lint CI → autofix → review routing) and introduce baseline security scans (CodeQL + Gitleaks), plus general repo hygiene automation.

Changes:

  • Add Copilot automation workflows for CI feedback loops, review requesting/forwarding, rebase help, and auto-assignment.
  • Add repo maintenance workflows (stale issue/PR handling, PR body cleanup).
  • Add security scanning workflows (CodeQL, Gitleaks) on master push/PR and schedules.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
.github/workflows/auto-approve-workflows.yml Scheduled dispatcher to re-trigger blocked Copilot-related workflows.
.github/workflows/automation-cleanup-pr-body.yml Cleans PR bodies on open (removes HTML comments/empty sections).
.github/workflows/automation-stale.yml Marks/closes stale issues/PRs on a schedule.
.github/workflows/copilot-auto-assign.yml Auto-selects and assigns Copilot to eligible priority issues.
.github/workflows/copilot-auto-review-llm.yml Uses local LLM + heuristics to triage Copilot Reviewer feedback and post fix requests.
.github/workflows/copilot-autofix.yml Attempts to auto-fix ruff issues after branch CI failures and push changes.
.github/workflows/copilot-branch-ci.yml Lightweight lint + syntax CI for copilot/** branches and PR feedback posting.
.github/workflows/copilot-ci-feedback.yml Posts fix requests to Copilot when main CI fails (with loop protection).
.github/workflows/copilot-ready-pr.yml Marks eligible Copilot draft PRs ready after CI success + minimum age.
.github/workflows/copilot-rebase.yml Helper to update Copilot PR branches against master.
.github/workflows/copilot-request-review.yml Requests Copilot Reviewer once Copilot signals work is finished.
.github/workflows/copilot-review-feedback.yml Summarizes new Copilot review suggestions back onto the PR.
.github/workflows/security-codeql.yml Runs CodeQL analysis for Python.
.github/workflows/security-gitleaks.yml Runs secret scanning via Gitleaks.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +22 to +28
- name: Install Gitleaks
run: |
curl -sSfL https://github.com/gitleaks/gitleaks/releases/download/v8.21.2/gitleaks_8.21.2_linux_x64.tar.gz | tar -xz
sudo mv gitleaks /usr/local/bin/

- name: Run Gitleaks (full scan)
run: gitleaks detect --source . --log-opts="--all" --verbose --exit-code 1

Copilot AI Feb 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Installing Gitleaks by piping curl output directly into tar and moving it with sudo is supply-chain risky and bypasses integrity verification. Prefer using the official gitleaks action or download the release and verify its checksum/signature before executing, and avoid requiring sudo on the runner.

Suggested change
- name: Install Gitleaks
run: |
curl -sSfL https://github.com/gitleaks/gitleaks/releases/download/v8.21.2/gitleaks_8.21.2_linux_x64.tar.gz | tar -xz
sudo mv gitleaks /usr/local/bin/
- name: Run Gitleaks (full scan)
run: gitleaks detect --source . --log-opts="--all" --verbose --exit-code 1
- name: Run Gitleaks (full scan)
uses: gitleaks/gitleaks-action@v2
with:
args: detect --source . --log-opts="--all" --verbose --exit-code 1

Copilot uses AI. Check for mistakes.

jobs:
cleanup:
runs-on: [self-hosted, Linux]

Copilot AI Feb 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This workflow triggers on pull_request:opened but runs on a self-hosted runner. Even though it doesn’t checkout code, it allows any PR opener (including forks) to consume self-hosted runner capacity. Consider moving this job to a GitHub-hosted runner unless there is a specific need for self-hosted.

Suggested change
runs-on: [self-hosted, Linux]
runs-on: ubuntu-latest

Copilot uses AI. Check for mistakes.

jobs:
stale:
runs-on: [self-hosted, Linux]

Copilot AI Feb 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This scheduled maintenance workflow doesn’t appear to require self-hosted resources, but it will occupy the self-hosted runner daily. Consider running it on a GitHub-hosted runner to reduce contention and avoid coupling repo hygiene automation to the availability of your self-hosted machine.

Suggested change
runs-on: [self-hosted, Linux]
runs-on: ubuntu-latest

Copilot uses AI. Check for mistakes.
Comment on lines +15 to +19
runs-on: [self-hosted, Linux]
permissions:
actions: read
contents: read
security-events: write

Copilot AI Feb 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This workflow runs on pull_request but uses a self-hosted runner. CodeQL analysis may execute parts of the project during extraction/autobuild, which is unsafe for untrusted PRs on a self-hosted machine. Consider running CodeQL on a GitHub-hosted runner instead (or restrict execution to trusted branches/events).

Copilot uses AI. Check for mistakes.
Comment on lines +83 to +85
if (!hasCopilotLabel && !(hasPriorityLabel && issue.assignees.length === 0)) {
return false;
}

Copilot AI Feb 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Candidates can include issues that already have non-Copilot assignees when the issue has the "copilot" label (there’s no check that issue.assignees is empty in that case). This matters because the assignment step later replaces assignees. Consider requiring issue.assignees.length === 0 for all candidates you intend to auto-assign.

Suggested change
if (!hasCopilotLabel && !(hasPriorityLabel && issue.assignees.length === 0)) {
return false;
}
const hasNoAssignees = issue.assignees.length === 0;
if (!hasNoAssignees) {
return false;
}
if (!hasCopilotLabel && !hasPriorityLabel) {
return false;
}

Copilot uses AI. Check for mistakes.
run: |
if git diff --quiet; then
echo "No style fixes needed - failure was from something else"
exit 1

Copilot AI Feb 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If no style changes are produced, this exits with status 1, which makes the autofix workflow fail even though it successfully determined there was nothing to fix. Consider exiting 0 (and logging that the failure was non-style) to avoid persistent red workflow runs/noise.

Suggested change
exit 1
exit 0

Copilot uses AI. Check for mistakes.
Comment on lines +160 to +161
MUTATION_JSON=$(printf '{"query":"mutation { replaceActorsForAssignable(input: {assignableId: \\"%s\\", actorIds: [\\"%s\\"]}) { assignable { ... on Issue { assignees(first: 10) { nodes { login } } } } } }"}' "$ISSUE_ID" "$COPILOT_BOT_ID")
RESULT=$(echo "$MUTATION_JSON" | gh api graphql --input - --jq '.data.replaceActorsForAssignable.assignable.assignees.nodes[].login')

Copilot AI Feb 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replaceActorsForAssignable will overwrite the entire assignee list with only the Copilot bot. If the issue had existing assignees, they will be removed. Prefer an API/mutation that adds Copilot as an additional assignee, or ensure the issue has zero assignees before calling this mutation.

Suggested change
MUTATION_JSON=$(printf '{"query":"mutation { replaceActorsForAssignable(input: {assignableId: \\"%s\\", actorIds: [\\"%s\\"]}) { assignable { ... on Issue { assignees(first: 10) { nodes { login } } } } } }"}' "$ISSUE_ID" "$COPILOT_BOT_ID")
RESULT=$(echo "$MUTATION_JSON" | gh api graphql --input - --jq '.data.replaceActorsForAssignable.assignable.assignees.nodes[].login')
MUTATION_JSON=$(printf '{"query":"mutation { addAssigneesToAssignable(input: {assignableId: \\"%s\\", assigneeIds: [\\"%s\\"]}) { assignable { ... on Issue { assignees(first: 10) { nodes { login } } } } } }"}' "$ISSUE_ID" "$COPILOT_BOT_ID")
RESULT=$(echo "$MUTATION_JSON" | gh api graphql --input - --jq '.data.addAssigneesToAssignable.assignable.assignees.nodes[].login')

Copilot uses AI. Check for mistakes.
Comment on lines +50 to +60
- name: Checkout
uses: actions/checkout@v4
with:
token: ${{ secrets.GH_PAT }}
fetch-depth: 0

- name: Configure git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

Copilot AI Feb 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These checkout/fetch steps don’t appear to be used since the workflow rebases via the GitHub API (pulls.updateBranch) and doesn’t run local git commands. Consider removing checkout (and git config) to reduce runtime and avoid using a write token unnecessarily.

Suggested change
- name: Checkout
uses: actions/checkout@v4
with:
token: ${{ secrets.GH_PAT }}
fetch-depth: 0
- name: Configure git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

Copilot uses AI. Check for mistakes.

MARKER="<!-- copilot-branch-ci:sha=$SHA -->"

if gh api "repos/$REPO/pulls/$PR_NUMBER/reviews?per_page=20" --jq '.[].body // ""' | grep -Fq "$MARKER"; then

Copilot AI Feb 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The duplicate-prevention check only fetches the last 20 PR reviews (per_page=20). On branches with more review comments over time, the marker could fall out of that window and the workflow may post duplicate reviews. Consider searching issue comments instead, or paginate/search all review bodies for the marker.

Suggested change
if gh api "repos/$REPO/pulls/$PR_NUMBER/reviews?per_page=20" --jq '.[].body // ""' | grep -Fq "$MARKER"; then
FOUND_MARKER=0
PAGE=1
while :; do
BODIES="$(gh api "repos/$REPO/pulls/$PR_NUMBER/reviews?per_page=100&page=$PAGE" --jq '.[].body // ""')"
# Stop if no more reviews are returned
if [ -z "$BODIES" ]; then
break
fi
if echo "$BODIES" | grep -Fq "$MARKER"; then
FOUND_MARKER=1
break
fi
PAGE=$((PAGE + 1))
done
if [ "$FOUND_MARKER" -eq 1 ]; then

Copilot uses AI. Check for mistakes.
Comment on lines +126 to +130
COPILOT_BOT_ID=$(gh api graphql -f query='
query($owner: String!, $name: String!) {
repository(owner: $owner, name: $name) {
suggestedActors(first: 100, capabilities: CAN_BE_ASSIGNED) {
nodes {

Copilot AI Feb 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This step depends on the gh CLI being present on the self-hosted runner. To avoid runner-specific failures, explicitly install gh (and any JSON tooling you rely on) in the workflow or guarantee it in runner provisioning.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants