Skip to content

Commit

Permalink
refactor(build): avoid release publishing race conditions
Browse files Browse the repository at this point in the history
Only run release jobs after all build jobs have completed, ensure only
one release job runs at a time, and also ensure update casks only runs
once after all release jobs have completed.
  • Loading branch information
jimeh committed Nov 25, 2024
1 parent e0c0d92 commit 099c107
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 39 deletions.
10 changes: 8 additions & 2 deletions .github/workflows/_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ name: _build
on:
workflow_call:
inputs:
should_run:
description: Whether or not to run the build job
type: boolean
default: false
artifact_prefix:
description: Artifact prefix
type: string
Expand Down Expand Up @@ -103,7 +107,6 @@ jobs:
check: ${{ steps.check.outputs.result }}
steps:
- name: Checkout build-emacs-for-macos repo
if: ${{ inputs.os != inputs.build_os }}
uses: actions/checkout@v4
with:
repository: jimeh/build-emacs-for-macos
Expand All @@ -124,8 +127,11 @@ jobs:
- name: Ensure emacs-builder is executable
if: ${{ inputs.os == inputs.build_os }}
run: chmod +x bin/emacs-builder
- uses: DeterminateSystems/nix-installer-action@main
- uses: DeterminateSystems/magic-nix-cache-action@main
- name: Plan build
run: >-
nix develop --command
bin/emacs-builder -l debug plan --output build-plan.yml
--output-dir '${{ github.workspace }}/builds'
${{ needs.prepare.outputs.test_plan_args }}
Expand Down Expand Up @@ -239,7 +245,7 @@ jobs:
KEYCHAIN_PATH="$RUNNER_TEMP/app-signing.keychain-db"
# import certificate and provisioning profile from secrets
echo -n "$CERT_BASE64" | base64 --decode --output "$CERTIFICATE_PATH"
echo -n "$CERT_BASE64" | base64 --decode > "$CERTIFICATE_PATH"
# create temporary keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
Expand Down
23 changes: 4 additions & 19 deletions .github/workflows/_release.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
---
# Requires _prepare.yml and _build.yml re-usable workflows to have run.
name: _release
concurrency:
group: _release
cancel-in-progress: false
on:
workflow_call:
inputs:
os:
description: GitHub Actions runner OS
type: string
required: false
default: "macos-12"
default: "macos-13"
plan_artifact:
description: Name of artifact containing a emacs-builder plan yaml file
type: string
Expand All @@ -17,15 +20,6 @@ on:
description: Name of artifact containing a *.dmg files to release
type: string
required: true
test_build_name:
description: "Test build name"
type: string
required: false
update_casks:
description: "Update casks in homebrew tap?"
type: boolean
required: true
default: true
secrets:
TAP_REPO_TOKEN:
description: Personal Access Token for Homebrew Tap repo
Expand Down Expand Up @@ -61,14 +55,5 @@ jobs:
$(find builds -name '*.dmg' -or -name '*.sha256')
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Trigger update casks workflow in homebrew tap
if: >-
steps.dmg.outputs.result != 'fail' &&
inputs.test_build_name == '' &&
inputs.update_casks
run: >-
gh workflow run --repo jimeh/homebrew-emacs-builds update-casks.yml
env:
GITHUB_TOKEN: ${{ secrets.TAP_REPO_TOKEN }}
- run: echo 'No DMG artifact available, was there a new commit to build?'
if: ${{ steps.dmg.outputs.result == 'fail' }}
27 changes: 27 additions & 0 deletions .github/workflows/_update-casks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
name: _update-casks
concurrency:
group: _update-casks
cancel-in-progress: false
on:
workflow_call:
inputs:
os:
description: GitHub Actions runner OS
type: string
required: false
default: "ubuntu-latest"
secrets:
TAP_REPO_TOKEN:
description: Personal Access Token for Homebrew Tap repo
required: true

jobs:
emacs-builds:
runs-on: ${{ inputs.os }}
steps:
- name: Trigger update casks workflow in homebrew tap
run: >-
gh workflow run --repo jimeh/homebrew-emacs-builds update-casks.yml
env:
GITHUB_TOKEN: ${{ secrets.TAP_REPO_TOKEN }}
51 changes: 40 additions & 11 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ on:
required: false
default: ""
os:
description: 'Runner OS ("macos-12", "macos-13", or "macos-latest")'
description: 'Runner OS ("macos-13", "macos-14", or "macos-latest")'
required: true
default: "macos-12"
default: "macos-13"
test_build_name:
description: "Test build name"
required: false
Expand Down Expand Up @@ -62,7 +62,7 @@ jobs:
needs: [prepare]
with:
os: ${{ github.event.inputs.os }}
build_os: "macos-12"
build_os: "macos-13"
artifact_prefix: "x86_64-"
git_ref: ${{ github.event.inputs.git_ref }}
git_sha: ${{ github.event.inputs.git_sha }}
Expand All @@ -82,14 +82,19 @@ jobs:
release_x86_64:
name: Release (x86_64)
uses: ./.github/workflows/_release.yml
needs: [build_x86_64]
if: ${{ needs.build_x86_64.outputs.package_created }}
# Depend on both build_x86_64 and build_arm64, but only run if build_x86_64
# was successful and a package was created. This ensure wait for all builds
# to complete before running any release jobs.
needs: [build_x86_64, build_arm64]
if: |
always() &&
needs.build_x86_64.result == 'success' &&
needs.build_x86_64.outputs.package_created &&
needs.build_arm64.result != 'failure'
with:
os: ${{ github.event.inputs.os }}
plan_artifact: x86_64-build-plan
dmg_artifact: x86_64-dmg
test_build_name: ${{ github.event.inputs.test_build_name }}
update_casks: true
secrets:
TAP_REPO_TOKEN: ${{ secrets.TAP_REPO_TOKEN }}

Expand Down Expand Up @@ -124,13 +129,37 @@ jobs:
release_arm64:
name: Release (arm64)
uses: ./.github/workflows/_release.yml
needs: [build_arm64]
if: ${{ needs.build_arm64.outputs.package_created }}
# Depend on both build_arm64 and build_x86_64, but only run if build_arm64
# was successful and a package was created. This ensure wait for all builds
# to complete before running any release jobs.
needs: [build_arm64, build_x86_64]
if: |
always() &&
needs.build_arm64.result == 'success' &&
needs.build_arm64.outputs.package_created &&
needs.build_x86_64.result != 'failure'
with:
os: ${{ github.event.inputs.os }}
plan_artifact: arm64-build-plan
dmg_artifact: arm64-dmg
test_build_name: ${{ github.event.inputs.test_build_name }}
update_casks: false
secrets:
TAP_REPO_TOKEN: ${{ secrets.TAP_REPO_TOKEN }}

# ----------------------------------------------------------------------------
# Trigger update casks workflow in homebrew tap
# ----------------------------------------------------------------------------

update_casks:
name: Update Casks
uses: ./.github/workflows/_update-casks.yml
# Depend on both release jobs, but only run if either of them was
# successful. This ensures we only run this job once all release jobs have
# been completed.
needs: [release_x86_64, release_arm64]
if: >-
always() &&
github.event.inputs.test_build_name == '' &&
contains(needs.*.result, 'success') &&
!contains(needs.*.result, 'failure')
secrets:
TAP_REPO_TOKEN: ${{ secrets.TAP_REPO_TOKEN }}
45 changes: 38 additions & 7 deletions .github/workflows/nightly-master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
uses: ./.github/workflows/_build.yml
needs: [prepare]
with:
build_os: "macos-12"
build_os: "macos-13"
artifact_prefix: "x86_64-"
git_ref: "master"
git_sha: ${{ github.event.inputs.git_sha }}
Expand All @@ -48,12 +48,18 @@ jobs:
release_x86_64:
name: Release (x86_64)
uses: ./.github/workflows/_release.yml
needs: [build_x86_64]
if: ${{ needs.build_x86_64.outputs.package_created }}
# Depend on both build_x86_64 and build_arm64, but only run if build_x86_64
# was successful and a package was created. This ensure wait for all builds
# to complete before running any release jobs.
needs: [build_x86_64, build_arm64]
if: |
always() &&
needs.build_x86_64.result == 'success' &&
needs.build_x86_64.outputs.package_created &&
needs.build_arm64.result != 'failure'
with:
plan_artifact: x86_64-build-plan
dmg_artifact: x86_64-dmg
update_casks: true
secrets:
TAP_REPO_TOKEN: ${{ secrets.TAP_REPO_TOKEN }}

Expand Down Expand Up @@ -86,11 +92,36 @@ jobs:
release_arm64:
name: Release (arm64)
uses: ./.github/workflows/_release.yml
needs: [build_arm64]
if: ${{ needs.build_arm64.outputs.package_created }}
# Depend on both build_arm64 and build_x86_64, but only run if build_arm64
# was successful and a package was created. This ensure wait for all builds
# to complete before running any release jobs.
needs: [build_arm64, build_x86_64]
if: |
always() &&
needs.build_arm64.result == 'success' &&
needs.build_arm64.outputs.package_created &&
needs.build_x86_64.result != 'failure'
with:
plan_artifact: arm64-build-plan
dmg_artifact: arm64-dmg
update_casks: false
secrets:
TAP_REPO_TOKEN: ${{ secrets.TAP_REPO_TOKEN }}

# ----------------------------------------------------------------------------
# Trigger update casks workflow in homebrew tap
# ----------------------------------------------------------------------------

update_casks:
name: Update Casks
uses: ./.github/workflows/_update-casks.yml
# Depend on both release jobs, but only run if either of them was
# successful. This ensures we only run this job once all release jobs have
# been completed.
needs: [release_x86_64, release_arm64]
if: >-
always() &&
github.event.inputs.test_build_name == '' &&
contains(needs.*.result, 'success') &&
!contains(needs.*.result, 'failure')
secrets:
TAP_REPO_TOKEN: ${{ secrets.TAP_REPO_TOKEN }}

0 comments on commit 099c107

Please sign in to comment.