From b6f55fadbf9e3fd167096b1564c3d5c826f79e2b Mon Sep 17 00:00:00 2001 From: carlos-alm <127798846+carlos-alm@users.noreply.github.com> Date: Tue, 3 Mar 2026 03:23:17 -0700 Subject: [PATCH 1/2] fix: prevent duplicate benchmark PRs on stable releases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Benchmark workflow triggers on any Publish workflow completion. During a stable release, both a dev-push Publish (from merging PRs) and the release-event Publish complete successfully, each spawning a Benchmark run that resolves to the same stable version via git tag lookup — creating duplicate PRs. Two fixes: 1. Filter workflow_run triggers to exclude push-initiated Publish completions (dev builds should not benchmark the latest stable tag) 2. Check for existing open PRs before creating new ones as a safety net --- .github/workflows/benchmark.yml | 72 ++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 24 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index a63ca54c..e797211b 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -17,7 +17,8 @@ jobs: runs-on: ubuntu-latest if: >- github.event_name == 'workflow_dispatch' || - github.event.workflow_run.conclusion == 'success' + (github.event.workflow_run.conclusion == 'success' && + github.event.workflow_run.event != 'push') permissions: actions: read contents: write @@ -139,17 +140,23 @@ jobs: git commit -m "docs: update build performance benchmarks (${VERSION})" git push origin "$BRANCH" - gh pr create \ - --base main \ - --head "$BRANCH" \ - --title "docs: update build performance benchmarks (${VERSION})" \ - --body "Automated build benchmark update for **${VERSION}** from workflow run [#${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})." + TITLE="docs: update build performance benchmarks (${VERSION})" + if gh pr list --state open --json title --jq ".[].title" | grep -qF "$TITLE"; then + echo "::notice::PR already open for '$TITLE' — skipping" + else + gh pr create \ + --base main \ + --head "$BRANCH" \ + --title "$TITLE" \ + --body "Automated build benchmark update for **${VERSION}** from workflow run [#${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})." + fi embedding-benchmark: runs-on: ubuntu-latest if: >- github.event_name == 'workflow_dispatch' || - github.event.workflow_run.conclusion == 'success' + (github.event.workflow_run.conclusion == 'success' && + github.event.workflow_run.event != 'push') permissions: actions: read contents: write @@ -284,17 +291,23 @@ jobs: git commit -m "docs: update embedding benchmarks (${VERSION})" git push origin "$BRANCH" - gh pr create \ - --base main \ - --head "$BRANCH" \ - --title "docs: update embedding benchmarks (${VERSION})" \ - --body "Automated embedding benchmark update for **${VERSION}** from workflow run [#${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})." + TITLE="docs: update embedding benchmarks (${VERSION})" + if gh pr list --state open --json title --jq ".[].title" | grep -qF "$TITLE"; then + echo "::notice::PR already open for '$TITLE' — skipping" + else + gh pr create \ + --base main \ + --head "$BRANCH" \ + --title "$TITLE" \ + --body "Automated embedding benchmark update for **${VERSION}** from workflow run [#${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})." + fi query-benchmark: runs-on: ubuntu-latest if: >- github.event_name == 'workflow_dispatch' || - github.event.workflow_run.conclusion == 'success' + (github.event.workflow_run.conclusion == 'success' && + github.event.workflow_run.event != 'push') permissions: actions: read contents: write @@ -415,17 +428,23 @@ jobs: git commit -m "docs: update query benchmarks (${VERSION})" git push origin "$BRANCH" - gh pr create \ - --base main \ - --head "$BRANCH" \ - --title "docs: update query benchmarks (${VERSION})" \ - --body "Automated query benchmark update for **${VERSION}** from workflow run [#${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})." + TITLE="docs: update query benchmarks (${VERSION})" + if gh pr list --state open --json title --jq ".[].title" | grep -qF "$TITLE"; then + echo "::notice::PR already open for '$TITLE' — skipping" + else + gh pr create \ + --base main \ + --head "$BRANCH" \ + --title "$TITLE" \ + --body "Automated query benchmark update for **${VERSION}** from workflow run [#${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})." + fi incremental-benchmark: runs-on: ubuntu-latest if: >- github.event_name == 'workflow_dispatch' || - github.event.workflow_run.conclusion == 'success' + (github.event.workflow_run.conclusion == 'success' && + github.event.workflow_run.event != 'push') permissions: actions: read contents: write @@ -546,8 +565,13 @@ jobs: git commit -m "docs: update incremental benchmarks (${VERSION})" git push origin "$BRANCH" - gh pr create \ - --base main \ - --head "$BRANCH" \ - --title "docs: update incremental benchmarks (${VERSION})" \ - --body "Automated incremental benchmark update for **${VERSION}** from workflow run [#${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})." + TITLE="docs: update incremental benchmarks (${VERSION})" + if gh pr list --state open --json title --jq ".[].title" | grep -qF "$TITLE"; then + echo "::notice::PR already open for '$TITLE' — skipping" + else + gh pr create \ + --base main \ + --head "$BRANCH" \ + --title "$TITLE" \ + --body "Automated incremental benchmark update for **${VERSION}** from workflow run [#${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})." + fi From f4c3141e306ab091d8fe99f8e615282625653afc Mon Sep 17 00:00:00 2001 From: carlos-alm <127798846+carlos-alm@users.noreply.github.com> Date: Tue, 3 Mar 2026 19:10:22 -0700 Subject: [PATCH 2/2] ci: replace npm ci with npm install in benchmark and license workflows npm ci fails when package-lock.json is out of sync with package.json for the @optave/codegraph-* native binary optional deps, which are only published during the release process. npm install tolerates missing optional deps gracefully, matching how the main CI workflow already handles this. --- .github/workflows/benchmark.yml | 8 ++++---- .github/workflows/shield-license-compliance.yml | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index e797211b..0393e4b9 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -37,7 +37,7 @@ jobs: cache: "npm" - name: Install dependencies - run: npm ci --prefer-offline --no-audit --no-fund + run: npm install --prefer-offline --no-audit --no-fund - name: Determine benchmark mode id: mode @@ -175,7 +175,7 @@ jobs: cache: "npm" - name: Install dependencies - run: npm ci --prefer-offline --no-audit --no-fund + run: npm install --prefer-offline --no-audit --no-fund - name: Determine benchmark mode id: mode @@ -326,7 +326,7 @@ jobs: cache: "npm" - name: Install dependencies - run: npm ci --prefer-offline --no-audit --no-fund + run: npm install --prefer-offline --no-audit --no-fund - name: Determine benchmark mode id: mode @@ -463,7 +463,7 @@ jobs: cache: "npm" - name: Install dependencies - run: npm ci --prefer-offline --no-audit --no-fund + run: npm install --prefer-offline --no-audit --no-fund - name: Determine benchmark mode id: mode diff --git a/.github/workflows/shield-license-compliance.yml b/.github/workflows/shield-license-compliance.yml index 60f5b164..c9ba93ba 100644 --- a/.github/workflows/shield-license-compliance.yml +++ b/.github/workflows/shield-license-compliance.yml @@ -32,12 +32,12 @@ jobs: shell: bash run: | for attempt in 1 2 3; do - npm ci --prefer-offline --no-audit --no-fund --ignore-scripts && break + npm install --prefer-offline --no-audit --no-fund --ignore-scripts && break if [ "$attempt" -lt 3 ]; then - echo "::warning::npm ci attempt $attempt failed, retrying in 15s..." + echo "::warning::npm install attempt $attempt failed, retrying in 15s..." sleep 15 else - echo "::error::npm ci failed after 3 attempts" + echo "::error::npm install failed after 3 attempts" exit 1 fi done