Skip to content

Commit ce6d459

Browse files
ivoanjoeregon
authored andcommitted
Add support for skipping slow builds and reusing previous results
This PR follows from the discussion in #13 . It splits the workflow into two ways of working: 1. When skipping slow Ruby builds, it only does ruby-head builds; this means debug and asan builds from a previous release are reused 2. When not skipping slow Ruby builds, this workflow works exactly as before The "main" tricks are: 1. The matrix for the "build" job is now dynamic, allowing us to reduce the number of builds 2. There's a "reuse-slow" job that is run as alternative to download/reupload builds I think the final result is quite simple/maintainable, although I'll admit it took quite a few iterations to get to this point. Note that this PR does not do everything we discussed in #13 : 1. It doesn't create the stable 3.4 asan variant yet 2. It doesn't change the build cron schedule or use the skip_slow for anything other than manually triggered builds yet My thinking is, I wanted feedback on if this was the right way to go before investing on the latter parts. (But this PR is self-contained to go in as-is) How does it work? Here's an example run: * Without skip_slow: [run](https://github.com/DataDog/ruby-dev-builder/actions/runs/13326349375) / [resulting release](https://github.com/DataDog/ruby-dev-builder/releases/tag/v20250214.093006) * With skip_slow: [run](https://github.com/DataDog/ruby-dev-builder/actions/runs/13326366082) / [resulting release](https://github.com/DataDog/ruby-dev-builder/releases/tag/v20250214.093100) You may spot that 'ubuntu-24.04-arm' is missing: those runners were having a bad day when I was testing (segfaults and whatnot, often not even in Ruby but also in the rust compiler) so I removed them temporarily to be able to do a full green run.
1 parent 230f37f commit ce6d459

File tree

1 file changed

+69
-15
lines changed

1 file changed

+69
-15
lines changed

.github/workflows/build.yml

+69-15
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
name: CRuby Dev Builds
2+
permissions:
3+
contents: write
24
on:
35
workflow_dispatch:
6+
inputs:
7+
skip_slow:
8+
type: boolean
9+
default: false
410
push:
511
tags:
612
- '*'
@@ -11,8 +17,11 @@ jobs:
1117
name: Check if the latest ruby commit is already built
1218
runs-on: ubuntu-latest
1319
outputs:
14-
should_build: ${{ steps.check_commit.outputs.result }}
20+
should_build: ${{ steps.check_commit.outputs.should_build }}
1521
commit: ${{ steps.latest_commit.outputs.commit }}
22+
previous_release: ${{ steps.check_commit.outputs.previous_release }}
23+
build_matrix: ${{ steps.matrix.outputs.build_matrix }}
24+
reuse_matrix: ${{ steps.matrix.outputs.reuse_matrix }}
1625
steps:
1726
- name: Clone ruby
1827
uses: actions/checkout@v4
@@ -32,15 +41,32 @@ jobs:
3241
const latestDevCommit = "${{ steps.latest_commit.outputs.commit }}"
3342
const { owner, repo } = context.repo
3443
let { data: release } = await github.rest.repos.getLatestRelease({ owner, repo })
35-
const latestReleaseCommit = release.body.split('@')[1]
44+
const firstLine = release.body.split('\n')[0]
45+
const latestReleaseCommit = firstLine.split('@')[1]
3646
console.log(`Latest release commit: ${latestReleaseCommit}`)
3747
console.log(`Latest ruby commit: ${latestDevCommit}`)
38-
if (latestReleaseCommit === latestDevCommit) {
39-
return 'false'
40-
} else {
41-
return 'true'
42-
}
43-
result-encoding: string
48+
core.setOutput('should_build', latestReleaseCommit !== latestDevCommit)
49+
core.setOutput('previous_release', release.tag_name)
50+
- name: Compute build and reuse matrix
51+
uses: actions/github-script@v7
52+
id: matrix
53+
with:
54+
script: |
55+
const osList = ['ubuntu-20.04', 'ubuntu-22.04', 'ubuntu-24.04', 'ubuntu-22.04-arm', 'ubuntu-24.04-arm', 'macos-13', 'macos-14']
56+
const skipSlow = "${{ github.event_name == 'workflow_dispatch' && github.event.inputs.skip_slow == 'true' }}"
57+
const buildMatrix = JSON.stringify({
58+
os: osList,
59+
name: skipSlow === 'false' ? ['head', 'debug'] : ['head'],
60+
...(skipSlow === 'false' && { include: [{ os: 'ubuntu-24.04', name: 'asan' }] })
61+
})
62+
core.setOutput('build_matrix', buildMatrix)
63+
const reuseMatrix = JSON.stringify({
64+
os: osList,
65+
name: ['debug'],
66+
include: [{ os: 'ubuntu-24.04', name: 'asan' }]
67+
})
68+
core.setOutput('reuse_matrix', reuseMatrix)
69+
console.log(`build_matrix: ${buildMatrix}, reuse_matrix: ${reuseMatrix}`)
4470
4571
release:
4672
name: Create GitHub Release
@@ -64,24 +90,25 @@ jobs:
6490
tag=$(basename "${{ github.ref }}")
6591
fi
6692
echo "tag=$tag" >> $GITHUB_OUTPUT
93+
- name: Set release description to built hash
94+
run: echo "ruby/ruby@${{ needs.prepare.outputs.commit }}" >> release-description.md
95+
- name: Append note if buils were reused
96+
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.skip_slow == 'true' }}
97+
run: echo "Skipped building and reused builds from ${{ needs.prepare.outputs.previous_release }} for debug and asan rubies" >> release-description.md
6798
- name: Create Release
6899
env:
69100
GH_TOKEN: ${{ github.token }}
70101
GH_REPO: ${{ github.repository }}
71102
run: |
72103
tag="${{ steps.tag.outputs.tag }}"
73104
body="ruby/ruby@${{ needs.prepare.outputs.commit }}"
74-
gh release create --draft "$tag" --title "$tag" --notes "$body"
105+
gh release create --draft "$tag" --title "$tag" --notes-file release-description.md
75106
76107
build:
77108
needs: [prepare, release]
78109
strategy:
79110
fail-fast: false
80-
matrix:
81-
os: [ ubuntu-20.04, ubuntu-22.04, ubuntu-24.04, ubuntu-22.04-arm, ubuntu-24.04-arm, macos-13, macos-14 ]
82-
name: [ head, debug ]
83-
include:
84-
- { os: ubuntu-24.04, name: asan }
111+
matrix: ${{ fromJson(needs.prepare.outputs.build_matrix) }}
85112
runs-on: ${{ matrix.os }}
86113
steps:
87114
- name: Clone ruby
@@ -205,9 +232,36 @@ jobs:
205232
GH_REPO: ${{ github.repository }}
206233
run: gh release upload "${{ needs.release.outputs.tag }}" "ruby-${{ matrix.name }}-${{ steps.platform.outputs.platform }}.tar.gz"
207234

235+
reuse-slow:
236+
needs: [prepare, release]
237+
strategy:
238+
fail-fast: false
239+
matrix: ${{ fromJson(needs.prepare.outputs.reuse_matrix) }}
240+
runs-on: ${{ matrix.os }}
241+
env:
242+
GH_TOKEN: ${{ github.token }}
243+
GH_REPO: ${{ github.repository }}
244+
steps:
245+
- name: Set platform
246+
id: platform
247+
run: |
248+
platform=${{ matrix.os }}
249+
platform=${platform/macos-13/macos-latest}
250+
platform=${platform/macos-14/macos-13-arm64}
251+
platform=${platform/%-arm/-arm64}
252+
echo "platform=$platform" >> $GITHUB_OUTPUT
253+
- name: Download binaries from previous release
254+
run: gh release download "${{ needs.prepare.outputs.previous_release }}" --pattern "ruby-${{ matrix.name }}-${{ steps.platform.outputs.platform }}.tar.gz"
255+
- name: Re-upload Binaries
256+
run: gh release upload "${{ needs.release.outputs.tag }}" "ruby-${{ matrix.name }}-${{ steps.platform.outputs.platform }}.tar.gz"
257+
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.skip_slow == 'true' }}
258+
- name: (Empty step for when reuse is not applied)
259+
run: echo "Not reusing binaries. This step is a no-op." # We can't skip the whole job as publish depends on it, but we skip the uploading
260+
if: ${{ !(github.event_name == 'workflow_dispatch' && github.event.inputs.skip_slow == 'true') }}
261+
208262
publish:
209263
name: Publish Release
210-
needs: [release, build]
264+
needs: [release, build, reuse-slow]
211265
runs-on: ubuntu-latest
212266
steps:
213267
- name: Publish Release

0 commit comments

Comments
 (0)