mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-09-16 23:32:32 -04:00
chore(ci): reap closed-PR runs, add missing timeouts and concurrency guards (#6406)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
84aae4b589
commit
dc4a7345f5
15 files changed
+108
No files matched your search
@@ -28,9 +28,16 @@ permissions:
|
||||
id-token: write
|
||||
attestations: write
|
||||
|
||||
# Never allow two release pipelines to run at once — they race on tags,
|
||||
# release objects, and Play track state. Later dispatches queue.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
determine-tags:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 10
|
||||
outputs:
|
||||
tag_to_process: ${{ steps.calculate_tags.outputs.tag_to_process }}
|
||||
release_name: ${{ steps.calculate_tags.outputs.release_name }}
|
||||
@@ -158,6 +165,7 @@ jobs:
|
||||
needs: [determine-tags, call-release-workflow]
|
||||
if: ${{ (failure() || cancelled()) && !inputs.dry_run && inputs.channel == 'internal' }}
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v7.0.1
|
||||
|
||||
@@ -33,6 +33,7 @@ jobs:
|
||||
build:
|
||||
if: github.repository == 'meshtastic/Meshtastic-Android'
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7.0.1
|
||||
@@ -82,6 +83,7 @@ jobs:
|
||||
if: github.repository == 'meshtastic/Meshtastic-Android'
|
||||
needs: build
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 15
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
|
||||
@@ -19,6 +19,7 @@ jobs:
|
||||
build:
|
||||
if: github.repository == 'meshtastic/Meshtastic-Android'
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7.0.1
|
||||
@@ -101,6 +102,7 @@ jobs:
|
||||
if: github.repository == 'meshtastic/Meshtastic-Android'
|
||||
needs: build
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 15
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
|
||||
@@ -50,6 +50,7 @@ jobs:
|
||||
# APK build itself failed, the artifact download below fails and this job goes red.
|
||||
if: github.repository == 'meshtastic/Meshtastic-Android' && !cancelled()
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 10
|
||||
permissions:
|
||||
contents: write
|
||||
env:
|
||||
|
||||
@@ -26,12 +26,19 @@ on:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
# Partner Center submissions must never race (a release event overlapping a
|
||||
# manual retry would collide on the same in-progress submission). Serialize.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
msstore:
|
||||
# Belt and braces for release events — `released` should already exclude
|
||||
# these. workflow_dispatch has no release payload and passes through.
|
||||
if: ${{ !github.event.release.prerelease && !github.event.release.draft }}
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 60
|
||||
env:
|
||||
# Secrets aren't readable in step `if:` expressions; skip cleanly until
|
||||
# Partner Center is configured. Presence is gated on PRODUCT_ID alone so
|
||||
|
||||
@@ -16,9 +16,16 @@ on:
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
# Destructive (deletes releases + tags): serialize dispatches so two cleanups
|
||||
# can never interleave.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
cleanup_prereleases:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v7.0.1
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
name: PR Closed Cleanup
|
||||
|
||||
# When a PR is closed (merged or abandoned) its in-flight CI runs keep burning
|
||||
# runner slots to completion: per-PR concurrency groups only cancel on a NEW
|
||||
# push, and nothing pushes to a closed PR. Reap queued/in-progress
|
||||
# pull_request-event runs for the closed PR's head SHA (pull-request.yml,
|
||||
# verify-flatpak.yml, ...). Runs for older SHAs were already cancelled by the
|
||||
# per-PR concurrency group when that SHA was superseded.
|
||||
#
|
||||
# pull_request_target is required: the plain pull_request event gets a
|
||||
# read-only GITHUB_TOKEN for fork PRs, which cannot cancel runs. Per the
|
||||
# pull_request_target warnings, this workflow must never check out or execute
|
||||
# PR code — it only calls the Actions API.
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [closed]
|
||||
|
||||
permissions:
|
||||
actions: write
|
||||
|
||||
jobs:
|
||||
cancel-pr-runs:
|
||||
if: github.repository == 'meshtastic/Meshtastic-Android'
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- name: Cancel in-flight CI runs for the closed PR
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
ids_file="$(mktemp)"
|
||||
trap 'rm -f "$ids_file"' EXIT
|
||||
for status in queued in_progress; do
|
||||
gh api --paginate "repos/${{ github.repository }}/actions/runs?event=pull_request&status=${status}&head_sha=${HEAD_SHA}&per_page=100" \
|
||||
--jq '.workflow_runs[].id'
|
||||
done >"$ids_file"
|
||||
sort -u "$ids_file" | while read -r run_id; do
|
||||
echo "Cancelling run $run_id"
|
||||
gh run cancel "$run_id" --repo "${{ github.repository }}" || true
|
||||
done
|
||||
@@ -69,6 +69,7 @@ permissions:
|
||||
jobs:
|
||||
prepare-build-info:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 10
|
||||
outputs:
|
||||
APP_VERSION_NAME: ${{ steps.prep_version.outputs.APP_VERSION_NAME }}
|
||||
APP_VERSION_CODE: ${{ steps.calculate_version_code.outputs.versionCode }}
|
||||
@@ -106,6 +107,7 @@ jobs:
|
||||
|
||||
promote-release:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 30
|
||||
needs: [ prepare-build-info ]
|
||||
env:
|
||||
FROM_TRACK: ${{ inputs.from_channel == 'closed' && 'NewAlpha' || (inputs.from_channel == 'open' && 'beta' || 'internal') }}
|
||||
@@ -144,6 +146,7 @@ jobs:
|
||||
|
||||
update-github-release:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 10
|
||||
needs: [ prepare-build-info, promote-release ]
|
||||
# actions: write is scoped here — only this job's publish-workflow
|
||||
# dispatch needs it, and the other jobs must not get it. Job-level
|
||||
@@ -345,6 +348,7 @@ jobs:
|
||||
update-homebrew-cask:
|
||||
if: ${{ inputs.channel == 'production' }}
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 15
|
||||
needs: [ update-github-release ]
|
||||
steps:
|
||||
- name: Checkout code
|
||||
|
||||
@@ -15,6 +15,7 @@ jobs:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- name: Auto-label PR
|
||||
uses: actions/github-script@v9
|
||||
|
||||
@@ -90,6 +90,7 @@ permissions:
|
||||
jobs:
|
||||
prepare-build-info:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 10
|
||||
outputs:
|
||||
APP_VERSION_NAME: ${{ steps.prep_version.outputs.APP_VERSION_NAME }}
|
||||
APP_VERSION_CODE: ${{ steps.calculate_version_code.outputs.versionCode }}
|
||||
@@ -130,6 +131,7 @@ jobs:
|
||||
|
||||
release-google:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 90
|
||||
needs: [prepare-build-info]
|
||||
env:
|
||||
GRADLE_CACHE_URL: ${{ secrets.GRADLE_CACHE_URL }}
|
||||
@@ -214,6 +216,7 @@ jobs:
|
||||
|
||||
release-fdroid:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 90
|
||||
needs: [prepare-build-info]
|
||||
env:
|
||||
GRADLE_CACHE_URL: ${{ secrets.GRADLE_CACHE_URL }}
|
||||
@@ -274,6 +277,7 @@ jobs:
|
||||
release-desktop:
|
||||
if: ${{ inputs.build_desktop }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 90
|
||||
needs: [prepare-build-info]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -431,6 +435,7 @@ jobs:
|
||||
create-flatpak-src:
|
||||
if: ${{ inputs.build_flatpak_src }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 60
|
||||
needs: [prepare-build-info]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -487,6 +492,7 @@ jobs:
|
||||
release-flatpak-src:
|
||||
if: ${{ inputs.build_flatpak_src }}
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 30
|
||||
needs: [create-flatpak-src]
|
||||
steps:
|
||||
- name: Download Flatpak source artifacts
|
||||
@@ -524,6 +530,7 @@ jobs:
|
||||
github-release:
|
||||
if: ${{ !cancelled() && !failure() }}
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 15
|
||||
needs:
|
||||
- prepare-build-info
|
||||
- release-google
|
||||
|
||||
@@ -8,9 +8,16 @@ on:
|
||||
- cron: '0 0 * * *'
|
||||
workflow_dispatch: # Allow manual triggering
|
||||
|
||||
# Emulator runs take up to ~1 h; a manual dispatch overlapping the daily cron
|
||||
# would race on the scheduled-baseline branch. Later runs queue, never stack.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
regenerate:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 90
|
||||
if: github.repository == 'meshtastic/Meshtastic-Android'
|
||||
permissions:
|
||||
contents: write # To commit files and push branches
|
||||
|
||||
@@ -7,9 +7,16 @@ on:
|
||||
- cron: '0 * * * *'
|
||||
workflow_dispatch: # Allow manual triggering
|
||||
|
||||
# Hourly cron + manual dispatch must never stack: overlapping runs race on the
|
||||
# scheduled-updates branch force-push. Later runs queue (at most one pending).
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
update_assets:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 30
|
||||
if: github.repository == 'meshtastic/Meshtastic-Android'
|
||||
permissions:
|
||||
contents: write # To commit files and push branches
|
||||
|
||||
@@ -8,10 +8,15 @@ permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
stale_issues:
|
||||
name: Close Stale Issues
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 15
|
||||
if: github.repository == 'meshtastic/Meshtastic-Android'
|
||||
|
||||
steps:
|
||||
|
||||
@@ -19,6 +19,7 @@ concurrency:
|
||||
jobs:
|
||||
update-changelog:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v7.0.1
|
||||
|
||||
@@ -25,12 +25,19 @@ on:
|
||||
# nothing in this repo is written.
|
||||
permissions: {}
|
||||
|
||||
# Serialize submissions: a release event overlapping a manual retry would open
|
||||
# duplicate winget-pkgs PRs for the same version.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
winget:
|
||||
# Belt and braces for release events — `released` should already exclude
|
||||
# these. workflow_dispatch has no release payload and passes through.
|
||||
if: ${{ !github.event.release.prerelease && !github.event.release.draft }}
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
env:
|
||||
# Secrets aren't readable in step `if:` expressions; skip cleanly until
|
||||
# the token is configured.
|
||||
|
||||
Reference in new issue
Block a user