Skip to content

general fixes & improvements #242

general fixes & improvements

general fixes & improvements #242

name: CI Orchestrator
on:
push:
branches: [ "main" ]
paths-ignore:
- 'docs/**'
- '**/*.md'
- '.github/workflows/**'
- 'images/**'
- 'LICENSE'
pull_request:
branches: [ "main" ]
paths-ignore:
- 'docs/**'
- '**/*.md'
- '.github/workflows/**'
- 'images/**'
- 'LICENSE'
release:
types: [ published ]
workflow_dispatch:
inputs:
mode:
description: 'Execution Mode'
required: true
default: 'Economy'
type: choice
options:
- Economy
- Full
jobs:
# Label PRs based on changed files
label-pr:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/labeler@v6
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
sync-labels: true
# Determine if we should run expensive tests
decision:
runs-on: ubuntu-latest
outputs:
run_e2e: ${{ steps.calc.outputs.run_e2e }}
steps:
- uses: actions/checkout@v6
- name: Check for file changes
uses: dorny/paths-filter@v3
id: filter
with:
filters: |
gui:
- 'src/switchcraft/gui_modern/**'
- 'src/switchcraft/auth_service.py'
- 'tests/test_ui_interactions.py'
- 'tests/test_github_login_integration.py'
- '.github/workflows/test.yml'
- id: calc
run: |
FORCE_RUN=false
if [[ "${{ github.event_name }}" == "release" || "${{ inputs.mode }}" == "Full" || "${{ github.ref }}" == "refs/heads/main" ]]; then
FORCE_RUN=true
fi
# Check for label
HAS_LABEL=false
if [[ "${{ contains(github.event.pull_request.labels.*.name, 'run-e2e') }}" == "true" ]]; then
HAS_LABEL=true
fi
# Check filter from previous step
GUI_CHANGED="${{ steps.filter.outputs.gui }}"
if [[ "$FORCE_RUN" == "true" || "$HAS_LABEL" == "true" || "$GUI_CHANGED" == "true" ]]; then
echo "run_e2e=true" >> $GITHUB_OUTPUT
echo "::notice::E2E Tests Enabled (Force: $FORCE_RUN, Label: $HAS_LABEL, Files: $GUI_CHANGED)"
else
echo "run_e2e=false" >> $GITHUB_OUTPUT
echo "::notice::E2E Tests Skipped (Economy Mode)"
fi
lint:
permissions:
contents: write
uses: ./.github/workflows/lint.yml
test-backend:
needs: lint
uses: ./.github/workflows/test.yml
with:
component: backend
test-e2e:
needs: [lint, decision, test-backend]
if: needs.decision.outputs.run_e2e == 'true'
uses: ./.github/workflows/test.yml
with:
component: e2e
build:
needs: [test-backend]
uses: ./.github/workflows/build.yml
test-web-demo:
needs: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.13'
- name: Install Dependencies
run: |
pip install .
pip install flet==0.80.3
pip install Pillow
- name: Run Web Demo Build
run: python scripts/build_web_demo.py
auto-merge:
needs: [build, test-e2e]
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
permissions:
contents: write
pull-requests: write
checks: read
issues: write
steps:
- uses: actions/checkout@v6
- name: Check Criteria and Merge
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
echo "Processing PR #$PR_NUMBER for Auto-Merge..."
# 0. Check for no-auto-merge label
echo "Checking for no-auto-merge label..."
HAS_NO_AUTO_MERGE=$(gh pr view "$PR_NUMBER" --json labels --jq '.labels[] | select(.name == "no-auto-merge") | .name' | head -n 1)
if [[ -n "$HAS_NO_AUTO_MERGE" ]]; then
echo "::notice::PR has 'no-auto-merge' label. Skipping auto-merge."
# Check if comment already exists to avoid duplicates
COMMENT_EXISTS=$(gh api "repos/$REPO/issues/$PR_NUMBER/comments" --jq '.[] | select(.body | contains("Auto-Merge Skipped") and contains("no-auto-merge")) | .id' | head -n 1)
if [[ -z "$COMMENT_EXISTS" ]]; then
# Post a comment explaining why auto-merge was skipped (only if not already posted)
# Use heredoc to preserve multi-line message and avoid YAML parsing issues
BODY=$'🚫 **Auto-Merge Skipped**\n\nThis PR has the `no-auto-merge` label. Auto-merge was not executed.\n\nTo enable auto-merge, please remove the `no-auto-merge` label.'
gh pr comment "$PR_NUMBER" --body "$BODY"
fi
exit 0
fi
echo "No 'no-auto-merge' label found. Proceeding..."
# 1. Check CI Status
# Implicitly passed because this job 'needs' build/test-backend.
echo "CI Orchestrator pipeline passed."
# 2. Check PR Author Permissions (Security Restriction)
PR_AUTHOR=$(gh pr view "$PR_NUMBER" --json author --jq '.author.login')
echo "PR Author: $PR_AUTHOR"
if [[ "$PR_AUTHOR" == *"[bot]" ]]; then
echo "PR Author is a Bot. Allowed."
else
PERM=$(gh api "repos/$REPO/collaborators/$PR_AUTHOR/permission" --jq '.permission')
echo "Author Permission: $PERM"
if [[ "$PERM" == "admin" || "$PERM" == "maintain" || "$PERM" == "write" ]]; then
echo "Author has trusted permission ($PERM). Allowed."
else
echo "::notice::PR Author ($PR_AUTHOR) does not have sufficient permissions ($PERM) for auto-merge. Skipping."
exit 0
fi
fi
# 3. Check Coderabbit Status
echo "Checking Coderabbit status..."
IS_APPROVED=$(gh api "repos/$REPO/pulls/$PR_NUMBER/reviews" --jq '.[] | select(.user.login == "coderabbitai[bot]" and .state == "APPROVED") | .state' | head -n 1)
HAS_SKIP_COMMENT=$(gh api "repos/$REPO/issues/$PR_NUMBER/comments" --jq '.[] | select(.user.login == "coderabbitai[bot]" and (.body | test("skip"; "i"))) | .id' | head -n 1)
if [[ -n "$IS_APPROVED" ]]; then
echo "Coderabbit APPROVED."
elif [[ -n "$HAS_SKIP_COMMENT" ]]; then
echo "Coderabbit SKIPPED review."
else
echo "::notice::Coderabbit has not approved or skipped yet. Waiting."
exit 0
fi
# 4. Attempt Merge
gh pr merge "$PR_NUMBER" --merge --auto --delete-branch