From 1aa0fd16e7445369451e38bf0116862310f5afae Mon Sep 17 00:00:00 2001 From: Will Jones Date: Thu, 2 Oct 2025 08:24:16 -0700 Subject: [PATCH] ci: automatic issue creation for failed publish workflows (#2694) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Created custom GitHub Action that creates issues when workflow jobs fail - Added report-failure jobs to cargo-publish.yml, java-publish.yml, npm-publish.yml, and pypi-publish.yml - Issues are created automatically with workflow name, failed job names, and run URL ## Test plan - Workflows will only create issues on actual release or workflow_dispatch events - Can be tested by triggering workflow_dispatch on a publish workflow Based on lancedb/lance#4873 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude --- .../actions/create-failure-issue/action.yml | 45 +++++++++++++++++++ .github/workflows/cargo-publish.yml | 14 ++++++ .github/workflows/java-publish.yml | 15 ++++++- .github/workflows/npm-publish.yml | 14 ++++++ .github/workflows/pypi-publish.yml | 14 ++++++ 5 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 .github/actions/create-failure-issue/action.yml diff --git a/.github/actions/create-failure-issue/action.yml b/.github/actions/create-failure-issue/action.yml new file mode 100644 index 00000000..832dc8de --- /dev/null +++ b/.github/actions/create-failure-issue/action.yml @@ -0,0 +1,45 @@ +name: Create Failure Issue +description: Creates a GitHub issue if any jobs in the workflow failed + +inputs: + job-results: + description: 'JSON string of job results from needs context' + required: true + workflow-name: + description: 'Name of the workflow' + required: true + +runs: + using: composite + steps: + - name: Check for failures and create issue + shell: bash + env: + JOB_RESULTS: ${{ inputs.job-results }} + WORKFLOW_NAME: ${{ inputs.workflow-name }} + RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + GH_TOKEN: ${{ github.token }} + run: | + # Check if any job failed + if echo "$JOB_RESULTS" | jq -e 'to_entries | any(.value.result == "failure")' > /dev/null; then + echo "Detected job failures, creating issue..." + + # Extract failed job names + FAILED_JOBS=$(echo "$JOB_RESULTS" | jq -r 'to_entries | map(select(.value.result == "failure")) | map(.key) | join(", ")') + + # Create issue with workflow name, failed jobs, and run URL + gh issue create \ + --title "$WORKFLOW_NAME Failed ($FAILED_JOBS)" \ + --body "The workflow **$WORKFLOW_NAME** failed during execution. + + **Failed jobs:** $FAILED_JOBS + + **Run URL:** $RUN_URL + + Please investigate the failed jobs and address any issues." \ + --label "ci" + + echo "Issue created successfully" + else + echo "No job failures detected, skipping issue creation" + fi diff --git a/.github/workflows/cargo-publish.yml b/.github/workflows/cargo-publish.yml index 1243395c..ab0683fe 100644 --- a/.github/workflows/cargo-publish.yml +++ b/.github/workflows/cargo-publish.yml @@ -38,3 +38,17 @@ jobs: - name: Publish the package run: | cargo publish -p lancedb --all-features --token ${{ steps.auth.outputs.token }} + report-failure: + name: Report Workflow Failure + runs-on: ubuntu-latest + needs: [build] + if: always() && (github.event_name == 'release' || github.event_name == 'workflow_dispatch') + permissions: + contents: read + issues: write + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/create-failure-issue + with: + job-results: ${{ toJSON(needs) }} + workflow-name: ${{ github.workflow }} diff --git a/.github/workflows/java-publish.yml b/.github/workflows/java-publish.yml index 37d482ee..eca792f3 100644 --- a/.github/workflows/java-publish.yml +++ b/.github/workflows/java-publish.yml @@ -43,7 +43,6 @@ jobs: - uses: Swatinem/rust-cache@v2 - uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: "1.81.0" cache-workspaces: "./java/core/lancedb-jni" # Disable full debug symbol generation to speed up CI build and keep memory down # "1" means line tables only, which is useful for panic tracebacks. @@ -112,3 +111,17 @@ jobs: env: SONATYPE_USER: ${{ secrets.SONATYPE_USER }} SONATYPE_TOKEN: ${{ secrets.SONATYPE_TOKEN }} + report-failure: + name: Report Workflow Failure + runs-on: ubuntu-latest + needs: [linux-arm64, linux-x86, macos-arm64] + if: always() && (github.event_name == 'release' || github.event_name == 'workflow_dispatch') + permissions: + contents: read + issues: write + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/create-failure-issue + with: + job-results: ${{ toJSON(needs) }} + workflow-name: ${{ github.workflow }} diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index 0651f793..41e8a8cf 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -365,3 +365,17 @@ jobs: ARGS="$ARGS --tag preview" fi npm publish $ARGS + report-failure: + name: Report Workflow Failure + runs-on: ubuntu-latest + needs: [build-lancedb, test-lancedb, publish] + if: always() && (github.event_name == 'release' || github.event_name == 'workflow_dispatch') + permissions: + contents: read + issues: write + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/create-failure-issue + with: + job-results: ${{ toJSON(needs) }} + workflow-name: ${{ github.workflow }} diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml index d9942a76..bfb162fc 100644 --- a/.github/workflows/pypi-publish.yml +++ b/.github/workflows/pypi-publish.yml @@ -173,3 +173,17 @@ jobs: generate_release_notes: false name: Python LanceDB v${{ steps.extract_version.outputs.version }} body: ${{ steps.python_release_notes.outputs.changelog }} + report-failure: + name: Report Workflow Failure + runs-on: ubuntu-latest + needs: [linux, mac, windows] + permissions: + contents: read + issues: write + if: always() && (github.event_name == 'release' || github.event_name == 'workflow_dispatch') + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/create-failure-issue + with: + job-results: ${{ toJSON(needs) }} + workflow-name: ${{ github.workflow }}