|
| 1 | +name: "Sync: Labels" |
| 2 | +run-name: "Sync labels after push to main" |
| 3 | + |
| 4 | +# Runs after any push to main to ensure labels match repository state |
| 5 | +# This fixes label propagation issues when PRs are merged manually |
| 6 | +on: |
| 7 | + push: |
| 8 | + branches: |
| 9 | + - main |
| 10 | + workflow_dispatch: |
| 11 | + |
| 12 | +jobs: |
| 13 | + sync-spec-labels: |
| 14 | + runs-on: ubuntu-latest |
| 15 | + permissions: |
| 16 | + issues: write |
| 17 | + contents: read |
| 18 | + |
| 19 | + steps: |
| 20 | + - name: Checkout repository |
| 21 | + uses: actions/checkout@v6 |
| 22 | + with: |
| 23 | + fetch-depth: 2 # Need to see what changed |
| 24 | + |
| 25 | + - name: Install yq for YAML parsing |
| 26 | + run: | |
| 27 | + sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 |
| 28 | + sudo chmod +x /usr/local/bin/yq |
| 29 | +
|
| 30 | + - name: Detect new specifications merged to main |
| 31 | + id: detect |
| 32 | + run: | |
| 33 | + # Get list of specifications added/modified in this push |
| 34 | + CHANGED_SPECS=$(git diff --name-only HEAD~1 HEAD | \ |
| 35 | + grep -oP 'plots/\K[^/]+(?=/specification\.(md|yaml))' | \ |
| 36 | + sort -u) |
| 37 | +
|
| 38 | + if [ -z "$CHANGED_SPECS" ]; then |
| 39 | + echo "::notice::No specification changes detected" |
| 40 | + echo "specs=" >> $GITHUB_OUTPUT |
| 41 | + exit 0 |
| 42 | + fi |
| 43 | +
|
| 44 | + echo "specs<<EOF" >> $GITHUB_OUTPUT |
| 45 | + echo "$CHANGED_SPECS" >> $GITHUB_OUTPUT |
| 46 | + echo "EOF" >> $GITHUB_OUTPUT |
| 47 | +
|
| 48 | + - name: Sync labels for merged specifications |
| 49 | + if: steps.detect.outputs.specs != '' |
| 50 | + env: |
| 51 | + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 52 | + run: | |
| 53 | + echo "${{ steps.detect.outputs.specs }}" | while read SPEC_ID; do |
| 54 | + [ -z "$SPEC_ID" ] && continue |
| 55 | +
|
| 56 | + # Extract issue number from specification.yaml |
| 57 | + SPEC_YAML="plots/${SPEC_ID}/specification.yaml" |
| 58 | + if [ ! -f "$SPEC_YAML" ]; then |
| 59 | + echo "::warning::No specification.yaml for ${SPEC_ID}" |
| 60 | + continue |
| 61 | + fi |
| 62 | +
|
| 63 | + ISSUE=$(yq '.issue' "$SPEC_YAML" 2>/dev/null || echo "") |
| 64 | + if [ -z "$ISSUE" ] || [ "$ISSUE" == "null" ]; then |
| 65 | + echo "::warning::No issue number in ${SPEC_YAML}" |
| 66 | + continue |
| 67 | + fi |
| 68 | +
|
| 69 | + echo "::notice::Syncing labels for spec ${SPEC_ID} (issue #${ISSUE})" |
| 70 | +
|
| 71 | + # Get current labels |
| 72 | + CURRENT_LABELS=$(gh issue view "$ISSUE" --json labels -q '.labels[].name' 2>/dev/null || echo "") |
| 73 | +
|
| 74 | + # If specification is in main, ensure correct labels |
| 75 | + if echo "$CURRENT_LABELS" | grep -q "spec-request"; then |
| 76 | + echo "::notice::Removing spec-request label from #${ISSUE}" |
| 77 | + gh issue edit "$ISSUE" --remove-label "spec-request" 2>/dev/null || true |
| 78 | + fi |
| 79 | +
|
| 80 | + if ! echo "$CURRENT_LABELS" | grep -q "spec-ready"; then |
| 81 | + echo "::notice::Adding spec-ready label to #${ISSUE}" |
| 82 | + gh issue edit "$ISSUE" --add-label "spec-ready" 2>/dev/null || true |
| 83 | + fi |
| 84 | + done |
| 85 | +
|
| 86 | + sync-impl-labels: |
| 87 | + runs-on: ubuntu-latest |
| 88 | + permissions: |
| 89 | + issues: write |
| 90 | + contents: read |
| 91 | + |
| 92 | + steps: |
| 93 | + - name: Checkout repository |
| 94 | + uses: actions/checkout@v6 |
| 95 | + with: |
| 96 | + fetch-depth: 2 |
| 97 | + |
| 98 | + - name: Install yq for YAML parsing |
| 99 | + run: | |
| 100 | + sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 |
| 101 | + sudo chmod +x /usr/local/bin/yq |
| 102 | +
|
| 103 | + - name: Detect new implementations merged to main |
| 104 | + id: detect |
| 105 | + run: | |
| 106 | + # Get list of implementations added/modified in this push |
| 107 | + CHANGED_IMPLS=$(git diff --name-only HEAD~1 HEAD | \ |
| 108 | + grep -P 'plots/[^/]+/implementations/[^/]+\.py$') |
| 109 | +
|
| 110 | + if [ -z "$CHANGED_IMPLS" ]; then |
| 111 | + echo "::notice::No implementation changes detected" |
| 112 | + echo "impls=" >> $GITHUB_OUTPUT |
| 113 | + exit 0 |
| 114 | + fi |
| 115 | +
|
| 116 | + echo "impls<<EOF" >> $GITHUB_OUTPUT |
| 117 | + echo "$CHANGED_IMPLS" >> $GITHUB_OUTPUT |
| 118 | + echo "EOF" >> $GITHUB_OUTPUT |
| 119 | +
|
| 120 | + - name: Sync labels for merged implementations |
| 121 | + if: steps.detect.outputs.impls != '' |
| 122 | + env: |
| 123 | + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 124 | + run: | |
| 125 | + echo "${{ steps.detect.outputs.impls }}" | while read IMPL_PATH; do |
| 126 | + [ -z "$IMPL_PATH" ] && continue |
| 127 | +
|
| 128 | + # Extract spec-id and library from path: plots/{spec-id}/implementations/{library}.py |
| 129 | + SPEC_ID=$(echo "$IMPL_PATH" | cut -d'/' -f2) |
| 130 | + LIBRARY=$(echo "$IMPL_PATH" | cut -d'/' -f4 | sed 's/\.py$//') |
| 131 | +
|
| 132 | + # Get issue number |
| 133 | + SPEC_YAML="plots/${SPEC_ID}/specification.yaml" |
| 134 | + ISSUE=$(yq '.issue' "$SPEC_YAML" 2>/dev/null || echo "") |
| 135 | +
|
| 136 | + if [ -z "$ISSUE" ] || [ "$ISSUE" == "null" ]; then |
| 137 | + echo "::warning::No issue for ${SPEC_ID}/${LIBRARY}" |
| 138 | + continue |
| 139 | + fi |
| 140 | +
|
| 141 | + echo "::notice::Syncing labels for ${SPEC_ID}/${LIBRARY} (issue #${ISSUE})" |
| 142 | +
|
| 143 | + # Remove trigger and pending labels |
| 144 | + gh issue edit "$ISSUE" --remove-label "generate:${LIBRARY}" 2>/dev/null || true |
| 145 | + gh issue edit "$ISSUE" --remove-label "impl:${LIBRARY}:pending" 2>/dev/null || true |
| 146 | +
|
| 147 | + # Create and add done label |
| 148 | + gh label create "impl:${LIBRARY}:done" --color "0e8a16" \ |
| 149 | + --description "${LIBRARY} implementation merged" 2>/dev/null || true |
| 150 | + gh issue edit "$ISSUE" --add-label "impl:${LIBRARY}:done" 2>/dev/null || true |
| 151 | +
|
| 152 | + echo "::notice::✓ Labels synced for ${SPEC_ID}/${LIBRARY}" |
| 153 | + done |
0 commit comments