Skip to content
Draft
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
48 changes: 40 additions & 8 deletions .github/workflows/pr-run.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
name: Validate & Deploy Plugins

on:
# TEMPORARY, remove in a follow-up PR once this is merged: validate-and-deploy is a
# required status check, and a required check can never be satisfied by a PR that
# removes its own only trigger β€” pull_request_target (see below) always resolves from
# main, which doesn't have it yet, so it can't fire for *this* PR either. Keeping
# pull_request alive here just long enough for this PR to report its own required
# check; once merged, main has pull_request_target and every future PR is covered by
# it, so pull_request can come out again.
pull_request:
# GitHub always resolves the workflow file (and GITHUB_REF/GITHUB_SHA) for
# pull_request_target from the repo's actual default branch, never the PR's own
# branch β€” so a PR editing this file (fork or not) can't change what runs against it.
pull_request_target:
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Comment thread
coderabbitai[bot] marked this conversation as resolved.

# Serialize runs per PR so an older run (from a rapid follow-up push, or the transitional
# pull_request/pull_request_target overlap above) can't finish last and overwrite a newer
# deploy that reuses the same --suffix.
concurrency:
group: pr-run-${{ github.event.pull_request.number }}
cancel-in-progress: true
Comment on lines +17 to +22

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

πŸ—„οΈ Data Integrity & Integration | 🟠 Major | πŸ—οΈ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the workflow file structure first, then inspect the relevant slices.
ast-grep outline .github/workflows/pr-run.yaml --view expanded || true

printf '\n--- workflow excerpt ---\n'
cat -n .github/workflows/pr-run.yaml | sed -n '1,260p'

Repository: squaredup/plugins

Length of output: 10060


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find where the workflow uses pull_request / pull_request_target and where deploy happens.
rg -n "pull_request_target|pull_request|concurrency|cancel-in-progress|squaredup deploy|PLUGIN_PATHS|comments|API_KEY|token" .github/workflows/pr-run.yaml .github/workflows -g '*.yaml' -g '*.yml'

Repository: squaredup/plugins

Length of output: 5382


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n--- pr-cleanup workflow ---\n'
if [ -f .github/workflows/pr-cleanup.yaml ]; then
  cat -n .github/workflows/pr-cleanup.yaml
else
  echo "missing"
fi

printf '\n--- deploy-related references ---\n'
rg -n "squaredup deploy|cleanup|suffix|cancel-in-progress|concurrency" .github/workflows -g '*.yml' -g '*.yaml'

Repository: squaredup/plugins

Length of output: 1990


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect any docs or code that describe squaredup deploy behavior or suffix cleanup.
rg -n "squaredup deploy|--suffix|pr-cleanup|cleanup old|remove.*deployment|undeploy|delete.*deployment|tenant" . -g '*.md' -g '*.yaml' -g '*.yml' -g '*.js' -g '*.ts' -g '*.sh'

Repository: squaredup/plugins

Length of output: 541


Separate validation from deployment concurrency
.github/workflows/pr-run.yaml:20-22 uses one PR-wide group for both events, so a newer pull_request validation can cancel an in-flight pull_request_target deploy. Since deploy writes to the live tenant and reuses the same --suffix, that can leave partial PR state. Split the group by event, or disable cancellation for the deploy lane.

πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/pr-run.yaml around lines 17 - 22, Update the workflow
concurrency configuration around the pr-run concurrency group to separate
validation and deployment lanes by event, or disable cancellation for
pull_request_target deploy runs. Ensure a newer pull_request validation cannot
cancel an in-flight pull_request_target deployment, while preserving
serialization for runs that reuse the same PR suffix.

Source: MCP tools


jobs:
validate-and-deploy:
Expand All @@ -11,6 +29,7 @@ jobs:
steps:
- uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0

- name: Detect modified plugins
Expand All @@ -37,14 +56,18 @@ jobs:
env:
SQUAREDUP_API_KEY: ${{ secrets.SQUAREDUP_API_KEY }}
run: |
echo "Installing SquaredUp CLI..."
npm install -g @squaredup/cli
echo "Configuring SquaredUp CLI with API key..."
squaredup login --apiKey "$SQUAREDUP_API_KEY"
echo "Installing SquaredUp CLI..."
cd "$RUNNER_TEMP"
npm install -g @squaredup/cli
echo "SquaredUp CLI version: $(squaredup -v)"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
echo "Configuring SquaredUp CLI with API key..."
squaredup login --apiKey "$SQUAREDUP_API_KEY"

- name: Validate modified plugins
id: validate
if: steps.detect.outputs.plugins_modified == 'true'
env:
PLUGIN_PATHS: ${{ steps.detect.outputs.plugin_paths }}
run: |
validation_failed=false

Expand All @@ -66,7 +89,7 @@ jobs:
validation_failed=true
fi
echo ""
done <<< "${{ steps.detect.outputs.plugin_paths }}"
done <<< "$PLUGIN_PATHS"

if [ "$validation_failed" = "true" ]; then
echo "One or more plugins failed validation."
Expand All @@ -75,17 +98,26 @@ jobs:

- name: Deploy modified plugins
id: deploy
if: steps.detect.outputs.plugins_modified == 'true'
# Fork PRs only validate; deploying arbitrary fork-submitted plugin code (incl.
# scripts) to the live tenant needs a maintainer to merge/trigger it deliberately.
# Restricted to pull_request_target specifically while both triggers coexist
# (see TEMPORARY note above) β€” otherwise a same-repo PR would deploy twice per
# push, racing on the same --suffix.
if: steps.detect.outputs.plugins_modified == 'true' && github.event.pull_request.head.repo.full_name == github.repository && github.event_name == 'pull_request_target'
env:
PLUGIN_PATHS: ${{ steps.detect.outputs.plugin_paths }}
run: |
while IFS= read -r plugin_path; do
echo "Deploying ${plugin_path}..."
squaredup deploy "${plugin_path}" --suffix "${{ github.event.pull_request.number }}" --force
echo "Deployed ${plugin_path} successfully."
echo ""
done <<< "${{ steps.detect.outputs.plugin_paths }}"
done <<< "$PLUGIN_PATHS"

- name: Summary
if: always()
env:
PLUGIN_PATHS: ${{ steps.detect.outputs.plugin_paths }}
run: |
OUT=/tmp/summary.md

Expand All @@ -101,7 +133,7 @@ jobs:
echo "### πŸ“¦ Modified Plugins" >> $OUT
while IFS= read -r plugin_path; do
echo "- \`${plugin_path}\`" >> $OUT
done <<< "${{ steps.detect.outputs.plugin_paths }}"
done <<< "$PLUGIN_PATHS"
echo "" >> $OUT

echo "### πŸ“‹ Results" >> $OUT
Expand Down
Loading