Skip to content

Commit 3a1f9bc

Browse files
committed
Added paralelism to the offline archive build pipeline
1 parent 4160dbc commit 3a1f9bc

File tree

2 files changed

+161
-71
lines changed

2 files changed

+161
-71
lines changed

.github/workflows/build_offline_installer_archives.yaml

Lines changed: 147 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -41,25 +41,91 @@ on:
4141
types: [published]
4242

4343
jobs:
44+
# New setup job to determine build matrix
45+
setup-matrix:
46+
runs-on: ubuntu-latest
47+
outputs:
48+
matrix: ${{ steps.generate-matrix.outputs.matrix }}
49+
should_purge: ${{ steps.generate-matrix.outputs.should_purge }}
50+
steps:
51+
- name: Checkout (for scripts if needed)
52+
uses: actions/checkout@v4
53+
54+
- name: Download offline_installer_builder artifact
55+
uses: actions/download-artifact@v5
56+
with:
57+
pattern: offline_installer_builder-linux-x64-*
58+
merge-multiple: true
59+
path: ./
60+
github-token: ${{ secrets.GITHUB_TOKEN }}
61+
run-id: ${{ inputs.run_id || github.run_id }}
62+
63+
- name: Make binary executable
64+
run: chmod +x ./offline_installer_builder
65+
66+
- name: Install UV (Python package manager)
67+
run: cargo install --git https://github.com/astral-sh/uv uv
68+
69+
- name: Generate build matrix
70+
id: generate-matrix
71+
run: |
72+
# Get list of available IDF versions from the builder
73+
if [ -n "${{ inputs.idf_version }}" ]; then
74+
# Single version specified
75+
IDF_VERSIONS='["${{ inputs.idf_version }}"]'
76+
else
77+
# Get all available versions from the builder
78+
echo "Getting available IDF versions..."
79+
VERSIONS_OUTPUT=$(./offline_installer_builder --list-versions)
80+
echo "Raw versions output:"
81+
echo "$VERSIONS_OUTPUT"
82+
83+
# Convert newline-separated to JSON array
84+
IDF_VERSIONS=$(echo "$VERSIONS_OUTPUT" | jq -R -s -c 'split("\n") | map(select(length > 0))')
85+
echo "Parsed versions JSON:"
86+
echo "$IDF_VERSIONS"
87+
fi
88+
89+
# Platform configurations
90+
PLATFORMS='[
91+
{"os": "ubuntu-latest", "package_name": "linux-x64"},
92+
{"os": "ubuntu-24.04-arm", "package_name": "linux-aarch64"},
93+
{"os": "windows-latest", "package_name": "windows-x64"},
94+
{"os": "macos-latest", "package_name": "macos-aarch64"},
95+
{"os": "macos-13", "package_name": "macos-x64"}
96+
]'
97+
98+
# Create matrix combining versions and platforms
99+
MATRIX=$(jq -n \
100+
--argjson versions "$IDF_VERSIONS" \
101+
--argjson platforms "$PLATFORMS" \
102+
'{
103+
include: [
104+
$versions[] as $version |
105+
$platforms[] |
106+
. + {"idf_version": $version}
107+
]
108+
}')
109+
110+
echo "Generated matrix:"
111+
echo "$MATRIX" | jq .
112+
113+
echo "matrix=$MATRIX" >> $GITHUB_OUTPUT
114+
115+
# Determine if we should purge
116+
SHOULD_PURGE=$([ "${{ github.event_name }}" = "release" ] || [ "${{ inputs.purge_all }}" = "true" ] && echo "true" || echo "false")
117+
echo "should_purge=$SHOULD_PURGE" >> $GITHUB_OUTPUT
118+
119+
# Modified build job with dynamic matrix
44120
build-and-upload:
45-
name: Build & Upload (${{ matrix.package_name }})
121+
name: Build & Upload (${{ matrix.package_name }}, ${{ matrix.idf_version }})
122+
needs: setup-matrix
46123
runs-on: ${{ matrix.os }}
47124
continue-on-error: false
48125

49126
strategy:
50127
fail-fast: false
51-
matrix:
52-
include:
53-
- os: ubuntu-latest
54-
package_name: linux-x64
55-
- os: ubuntu-24.04-arm
56-
package_name: linux-aarch64
57-
- os: windows-latest
58-
package_name: windows-x64
59-
- os: macos-latest
60-
package_name: macos-aarch64
61-
- os: macos-13
62-
package_name: macos-x64
128+
matrix: ${{ fromJson(needs.setup-matrix.outputs.matrix) }}
63129

64130
steps:
65131
- name: Checkout (for scripts if needed)
@@ -76,12 +142,10 @@ jobs:
76142

77143
- name: Make binary executable (Unix)
78144
if: runner.os != 'Windows'
79-
run: |
80-
chmod +x ./offline_installer_builder
145+
run: chmod +x ./offline_installer_builder
81146

82147
- name: Install UV (Python package manager)
83-
run: |
84-
cargo install --git https://github.com/astral-sh/uv uv
148+
run: cargo install --git https://github.com/astral-sh/uv uv
85149

86150
- name: Set up AWS CLI
87151
uses: aws-actions/configure-aws-credentials@v4
@@ -127,18 +191,36 @@ jobs:
127191
Write-Host "Current offline_archives.json:"
128192
Get-Content "./offline_archives.json"
129193
130-
- name: Purge existing archives (if requested)
131-
if: github.event_name == 'release' || inputs.purge_all == true
194+
- name: Purge existing archives for this version (if requested)
195+
if: needs.setup-matrix.outputs.should_purge == 'true'
132196
run: |
133-
echo "Purging existing archives from S3..."
134-
jq -r '.[] | .filename' ./offline_archives.json | while read filename; do
135-
if [ -n "$filename" ]; then
136-
echo "Deleting s3://espdldata/dl/eim/$filename"
137-
aws s3 rm "s3://espdldata/dl/eim/$filename" || echo "Failed to delete $filename, continuing..."
138-
fi
139-
done
197+
echo "Purging existing archives for version ${{ matrix.idf_version }} from S3..."
140198
141-
- name: Build archives
199+
# Only purge archives for THIS specific version and platform
200+
PATTERN="archive_v${{ matrix.idf_version }}_${{ matrix.package_name }}.zst"
201+
202+
if [ "${{ runner.os }}" = "Windows" ]; then
203+
# PowerShell version
204+
$archives = aws s3 ls s3://espdldata/dl/eim/ | Where-Object { $_.Split()[-1] -match "archive_v${{ matrix.idf_version }}_${{ matrix.package_name }}\.zst" }
205+
foreach ($archive in $archives) {
206+
$filename = $archive.Split()[-1]
207+
if ($filename) {
208+
Write-Host "Deleting s3://espdldata/dl/eim/$filename"
209+
aws s3 rm "s3://espdldata/dl/eim/$filename"
210+
}
211+
}
212+
else
213+
# Bash version
214+
aws s3 ls s3://espdldata/dl/eim/ | grep "archive_v${{ matrix.idf_version }}_${{ matrix.package_name }}\.zst" | awk '{print $4}' | while read filename; do
215+
if [ -n "$filename" ]; then
216+
echo "Deleting s3://espdldata/dl/eim/$filename"
217+
aws s3 rm "s3://espdldata/dl/eim/$filename" || echo "Failed to delete $filename, continuing..."
218+
fi
219+
done
220+
fi
221+
shell: ${{ runner.os == 'Windows' && 'pwsh' || 'bash' }}
222+
223+
- name: Build archive for specific version
142224
id: build
143225
run: |
144226
# Determine binary name
@@ -148,19 +230,12 @@ jobs:
148230
BINARY="./offline_installer_builder"
149231
fi
150232
151-
# Determine arguments
152-
if [ -n "${{ inputs.idf_version }}" ]; then
153-
echo "Building specific version: ${{ inputs.idf_version }}"
154-
ARGS="-c default --idf-version-override ${{ inputs.idf_version }}"
155-
else
156-
echo "Building ALL versions"
157-
ARGS="-c default --build-all-versions"
158-
fi
233+
echo "Building specific version: ${{ matrix.idf_version }}"
159234
160-
# Run it
161-
$BINARY $ARGS
235+
# Build only this specific version
236+
$BINARY -c default --idf-version-override ${{ matrix.idf_version }}
162237
163-
# Collect and rename all built .zst files to include platform
238+
# Rename the built file to include platform
164239
PLATFORM="${{ matrix.package_name }}"
165240
mkdir -p built_archives
166241
@@ -184,50 +259,52 @@ jobs:
184259
echo "ERROR: No archives built!" >&2
185260
exit 1
186261
fi
187-
188262
shell: bash
189263

190-
- name: Upload archives to S3 and generate build info
264+
- name: Upload archive to S3 and generate build info
191265
id: upload
192266
run: |
193267
PLATFORM="${{ matrix.package_name }}"
194-
mkdir -p build-infos
268+
VERSION="${{ matrix.idf_version }}"
195269
196-
# Upload each .zst and record metadata
197-
for archive in built_archives/*.zst; do
198-
if [ ! -f "$archive" ]; then continue; fi
270+
# Should have exactly one file
271+
archive=$(ls built_archives/*.zst | head -1)
199272
200-
# Extract version from new filename: archive_v5.1.2_linux-x64.zst → 5.1.2
201-
FILENAME=$(basename "$archive")
202-
VERSION=$(echo "$FILENAME" | sed -E 's/archive_v([^_]+)_.*/\1/')
273+
if [ ! -f "$archive" ]; then
274+
echo "ERROR: No archive found!" >&2
275+
exit 1
276+
fi
203277
204-
# Get file size
205-
if [ "${{ runner.os }}" = "macOS" ]; then
206-
SIZE=$(stat -f %z "$archive")
207-
else
208-
SIZE=$(stat -c %s "$archive")
209-
fi
278+
FILENAME=$(basename "$archive")
210279
211-
# Upload to S3
212-
aws s3 cp --acl=public-read "$archive" "s3://espdldata/dl/eim/$FILENAME"
280+
# Get file size
281+
if [ "${{ runner.os }}" = "macOS" ]; then
282+
SIZE=$(stat -f %z "$archive")
283+
else
284+
SIZE=$(stat -c %s "$archive")
285+
fi
213286
214-
# Generate build info
215-
jq -n \
216-
--arg version "$VERSION" \
217-
--arg platform "$PLATFORM" \
218-
--arg filename "$FILENAME" \
219-
--argjson size $SIZE \
220-
'{"version": $version, "platform": $platform, "filename": $filename, "size": $size}' \
221-
> "build-infos/build-info-${VERSION}-${PLATFORM}.json"
287+
# Upload to S3
288+
aws s3 cp --acl=public-read "$archive" "s3://espdldata/dl/eim/$FILENAME"
222289
223-
echo "Uploaded $FILENAME ($SIZE bytes)"
224-
done
290+
# Generate build info
291+
mkdir -p build-info
292+
jq -n \
293+
--arg version "$VERSION" \
294+
--arg platform "$PLATFORM" \
295+
--arg filename "$FILENAME" \
296+
--argjson size $SIZE \
297+
'{"version": $version, "platform": $platform, "filename": $filename, "size": $size}' \
298+
> "build-info/build-info.json"
299+
300+
echo "Uploaded $FILENAME ($SIZE bytes)"
301+
shell: bash
225302

226-
- name: Save build infos as artifacts
303+
- name: Save build info as artifact
227304
uses: actions/upload-artifact@v4
228305
with:
229-
name: build-infos-${{ matrix.package_name }}
230-
path: build-infos/
306+
name: build-info-${{ matrix.idf_version }}-${{ matrix.package_name }}
307+
path: build-info/
231308
retention-days: 7
232309

233310
update-json:
@@ -251,15 +328,15 @@ jobs:
251328
- name: Download all build infos
252329
uses: actions/download-artifact@v4
253330
with:
254-
pattern: build-infos-*
331+
pattern: build-info-*
255332
path: ./all-build-infos/
256333
merge-multiple: true
257334

258335
- name: Merge and update JSON
259336
run: |
260337
# Collect all new entries
261338
NEW_ENTRIES="[]"
262-
for info_file in all-build-infos/build-infos/*/build-info-*.json; do
339+
for info_file in all-build-infos/build-info/build-info.json; do
263340
if [ -f "$info_file" ]; then
264341
echo "Processing: $info_file"
265342
entry=$(cat "$info_file")
@@ -271,7 +348,6 @@ jobs:
271348
CURRENT=$(cat offline_archives.json)
272349
273350
# Remove existing entries that are being replaced (same platform + version)
274-
# Keep entries for platforms/versions NOT rebuilt
275351
UPDATED=$(jq --argjson new "$NEW_ENTRIES" '
276352
. as $current |
277353
($new | map({version, platform})) as $to_replace |

src-tauri/src/offline_installer_builder.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,17 +368,31 @@ struct Args {
368368
/// Each version will create its own .zst archive file
369369
#[arg(long)]
370370
build_all_versions: bool,
371+
372+
/// List all supported IDF versions in machine-readable format and exit
373+
/// Output format: one version per line
374+
#[arg(long)]
375+
list_versions: bool,
371376
}
372377

373378
#[tokio::main]
374379
async fn main() {
375380
let args = Args::parse();
381+
if args.list_versions {
382+
let versions = idf_im_lib::idf_versions::get_idf_names().await;
383+
for version in versions {
384+
println!("{}", version);
385+
}
386+
return;
387+
}
376388

377389
// Setup logging
378390
if let Err(e) = setup_logging(args.verbose) {
379391
error!("Failed to initialize logging: {e}");
380392
}
381393

394+
395+
382396
if args.create_from_config.is_some() {
383397
info!(
384398
"Creating installation data from configuration file: {:?}",

0 commit comments

Comments
 (0)