-
Notifications
You must be signed in to change notification settings - Fork 3
394 lines (337 loc) · 14.9 KB
/
docker-build.yml
File metadata and controls
394 lines (337 loc) · 14.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
name: Docker Build
on:
push:
# Only build on tags, not branches
branches-ignore: ['**'] # Explicitly ignore all branches
tags:
- 'build-*' # Tags for builds only (no release)
- 'v*' # Tags for builds with releases (e.g., v1.0.0)
pull_request:
branches: [master, main]
paths-ignore:
- '**.md'
- 'docs/**'
workflow_dispatch:
inputs:
build_type:
description: 'Build type (minimal, standard, full)'
required: true
default: 'standard'
type: choice
options:
- minimal
- standard
- full
jobs:
# Job to determine which builds to run based on trigger type
setup:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
release: ${{ steps.check-release.outputs.should_release }}
steps:
- id: check-release
run: |
# Check if this is a release tag (starts with 'v')
if [[ "${{ github.ref }}" == refs/tags/v* ]]; then
echo "should_release=true" >> $GITHUB_OUTPUT
else
echo "should_release=false" >> $GITHUB_OUTPUT
fi
- id: set-matrix
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
# For manual triggers, only build the selected type
echo "matrix={\"include\":[{\"name\":\"${{ github.event.inputs.build_type }}\",\"build_args\":\"--profile=${{ github.event.inputs.build_type }} --compression-tool=upx\"}]}" >> $GITHUB_OUTPUT
else
# For automatic triggers, build all types with UPX compression
echo "matrix={\"include\":[{\"name\":\"minimal\",\"build_args\":\"--profile=minimal --compression-tool=upx\"},{\"name\":\"standard\",\"build_args\":\"--profile=standard --compression-tool=upx\"},{\"name\":\"full\",\"build_args\":\"--profile=full --compression-tool=upx\"}]}" >> $GITHUB_OUTPUT
fi
# Build job using Docker with the same setup as local builds
build:
needs: setup
runs-on: ubuntu-latest
strategy:
matrix: ${{fromJson(needs.setup.outputs.matrix)}}
fail-fast: false
name: Build OneFileLinux (${{ matrix.name }})
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up build dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential gcc g++ make autoconf automake libtool libelf-dev upx-ucl unzip zstd xz-utils ccache uuid-dev libuuid1 libblkid-dev libtirpc-dev
# Verify Docker is installed and running (GitHub Actions has Docker pre-installed)
docker --version
# Set up Docker Compose (either install it or create wrapper for docker compose plugin)
if ! command -v docker-compose &> /dev/null; then
echo "docker-compose command not found, setting up alternatives..."
# First try to use docker compose plugin if available
if docker compose version &> /dev/null; then
echo "Docker Compose plugin is available, creating wrapper script"
echo '#!/bin/bash
docker compose "$@"' > /tmp/docker-compose
chmod +x /tmp/docker-compose
sudo mv /tmp/docker-compose /usr/local/bin/docker-compose
else
# If plugin not available, install docker-compose binary
echo "Installing docker-compose from GitHub releases"
sudo curl -L "https://github.com/docker/compose/releases/download/v2.24.6/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
fi
fi
# Verify docker-compose is now available
docker-compose --version || echo "Warning: docker-compose not available, will use docker compose plugin directly"
# Create output directories with appropriate permissions and ensure docker can write to them
mkdir -p build/output output
sudo chown -R $(id -u):$(id -g) build output
sudo chmod -R 777 build output
# Create a .build_progress file with correct permissions if it doesn't exist
touch build/.build_progress
chmod 666 build/.build_progress
# Make all scripts executable
chmod -R +x build/*.sh docker/*.sh
find build/tools -name "*.sh" -exec chmod +x {} \; 2>/dev/null || true
- name: Cache Alpine kernel configs
uses: actions/cache@v4
with:
path: build/zfiles/kernel-configs
key: alpine-kernel-config-${{ hashFiles('build/80_common.sh') }}
restore-keys: |
alpine-kernel-config-
- name: Set up ccache
uses: actions/cache@v4
with:
path: ~/.ccache
key: ccache-${{ runner.os }}-${{ matrix.name }}-${{ github.sha }}
restore-keys: |
ccache-${{ runner.os }}-${{ matrix.name }}-
ccache-${{ runner.os }}-
# Create custom env file for GitHub Actions using the same docker-compose setup as local
- name: Configure build environment
run: |
# Create .env file with GitHub-specific settings
cat > docker/.env << EOF
# GitHub Actions build environment
# Generated at $(date)
# Build arguments from matrix
BUILD_ARGS=${{ matrix.build_args }}
# Resource allocations appropriate for GitHub runners
DOCKER_MEMORY=7g
DOCKER_CPUS=2
# User ID mapping - use the runner's UID/GID
HOST_UID=$(id -u)
HOST_GID=$(id -g)
# GitHub-specific settings
GITHUB_ACTIONS=true
# Run as root to avoid permission issues
RUN_AS_ROOT=true
RUN_AS_USER=root
# Use default password 'onefilelinux' instead of generating a random one
GENERATE_RANDOM_PASSWORD=false
ROOT_PASSWORD=onefilelinux
# Debug settings
DEBUG_FEATURE_FLAGS=true
EOF
# Also prepare build directory for Docker entrypoint
mkdir -p build/.onefilelinux
touch build/.onefilelinux/host_uid_gid
echo "$(id -u):$(id -g)" > build/.onefilelinux/host_uid_gid
chmod 666 build/.onefilelinux/host_uid_gid
# Create ccache directory with proper permissions
mkdir -p ~/.ccache
sudo chmod -R 777 ~/.ccache
# Copy any existing kernel configs to the expected location
mkdir -p build/zfiles/kernel-configs/features
chmod -R 777 build/zfiles/kernel-configs
# Run the build using the same docker-compose setup as local builds
- name: Build OneFileLinux using Docker
env:
BUILD_ARGS: ${{ matrix.build_args }}
GENERATE_RANDOM_PASSWORD: "false"
ROOT_PASSWORD: "onefilelinux"
run: |
cd docker
# Show configuration
echo "Building with arguments: $BUILD_ARGS"
cat .env
# Set environment variables for Docker
export HOST_UID=$(id -u)
export HOST_GID=$(id -g)
echo "Setting HOST_UID=$HOST_UID and HOST_GID=$HOST_GID in environment"
# Use the local docker-compose setup for builds
# Try both docker-compose and docker compose commands
if command -v docker-compose &> /dev/null; then
echo "Using docker-compose command"
docker-compose up --build
COMPOSE_EXIT_CODE=$?
else
echo "Using docker compose plugin directly"
docker compose up --build
COMPOSE_EXIT_CODE=$?
fi
# Check the exit code
if [ $COMPOSE_EXIT_CODE -ne 0 ]; then
echo "Docker build failed with exit code: $COMPOSE_EXIT_CODE"
if command -v docker-compose &> /dev/null; then
docker-compose logs
else
docker compose logs
fi
exit 1
fi
# Show output directory
echo "Build output files:"
ls -la ../output/
# If we need to apply any GitHub-specific fixes to output files, do it here
- name: Check for build artifacts
id: check_files
run: |
# Find all EFI files in the output directory
echo "Searching for build artifacts in ./output/"
ls -la ./output/ || true
# Find EFI files (including those with custom names)
EFI_FILES=$(find ./output/ -name "*.efi" | sort)
if [ -n "$EFI_FILES" ]; then
echo "efi_file=true" >> $GITHUB_OUTPUT
# Check if we have a profile-specific EFI first
PROFILE_EFI="./output/OneFileLinux-${{ matrix.name }}.efi"
GENERIC_EFI="./output/OneFileLinux.efi"
# Look for custom profile names (contain 'custom' in the name)
CUSTOM_EFI=$(echo "$EFI_FILES" | grep -i "custom" | head -1)
# Prioritize files in this order: Profile-specific > Custom > Generic
if [ -f "$PROFILE_EFI" ]; then
PRIMARY_EFI="$PROFILE_EFI"
echo "efi_path=$PROFILE_EFI" >> $GITHUB_OUTPUT
echo "Found profile-specific EFI file: $PROFILE_EFI"
elif [ -n "$CUSTOM_EFI" ] && [ -f "$CUSTOM_EFI" ]; then
PRIMARY_EFI="$CUSTOM_EFI"
echo "efi_path=$CUSTOM_EFI" >> $GITHUB_OUTPUT
echo "Found custom profile EFI file: $CUSTOM_EFI"
elif [ -f "$GENERIC_EFI" ]; then
PRIMARY_EFI="$GENERIC_EFI"
echo "efi_path=$GENERIC_EFI" >> $GITHUB_OUTPUT
echo "Found generic EFI file: $GENERIC_EFI"
# Copy it to the profile-specific name for consistent artifacts
cp "$GENERIC_EFI" "$PROFILE_EFI"
echo "Copied to: $PROFILE_EFI"
else
# If none of the expected names are found, use the first EFI file
PRIMARY_EFI=$(echo "$EFI_FILES" | head -1)
echo "efi_path=$PRIMARY_EFI" >> $GITHUB_OUTPUT
echo "Found alternative EFI file: $PRIMARY_EFI"
fi
# Show information about the primary EFI file
du -h "$PRIMARY_EFI"
# List all EFI files found (for comprehensive logging)
echo "All EFI files found:"
for efi in $EFI_FILES; do
file_size=$(du -h "$efi" | cut -f1)
echo "- $efi (Size: $file_size)"
done
else
echo "efi_file=false" >> $GITHUB_OUTPUT
echo "Build failed to produce any EFI file"
ls -la ./output/
exit 1
fi
# Display timing data if available
if [ -f "./build/build_timing.log" ]; then
echo "Build Timing Data:"
cat ./build/build_timing.log
fi
- name: Upload build artifact
if: steps.check_files.outputs.efi_file == 'true'
uses: actions/upload-artifact@v4
with:
name: OneFileLinux-${{ matrix.name }}
# Upload all EFI files to ensure custom profiles are included
path: |
./output/*.efi
if-no-files-found: error
- name: Upload build timing log
if: always()
uses: actions/upload-artifact@v4
with:
name: build-timing-log-${{ matrix.name }}
path: ./build/build_timing.log
if-no-files-found: warn
# Release job - now conditional on the tag pattern only
release:
name: Package and Release
needs: [setup, build]
# Only run release job for 'v*' tags
if: needs.setup.outputs.release == 'true'
runs-on: ubuntu-latest
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: ./artifacts
- name: Create release package
run: |
mkdir -p release
# Copy all EFI files from each artifact directory to the release directory
echo "Examining artifact directories:"
ls -la ./artifacts/
# Loop through all artifact directories
for artifact_dir in ./artifacts/OneFileLinux-*/; do
if [ -d "$artifact_dir" ]; then
echo "Processing artifact directory: $artifact_dir"
ls -la "$artifact_dir"
# Get the artifact name (last part of the directory path)
artifact_name=$(basename "$artifact_dir")
# Find all EFI files in the artifact directory
for efi_file in "$artifact_dir"/*.efi; do
if [ -f "$efi_file" ]; then
# Use the original filename if it's profile-specific (contains a hyphen)
# Otherwise rename it based on the artifact name
efi_basename=$(basename "$efi_file")
if [[ "$efi_basename" == *"-"* ]]; then
# Already has a profile in the name, keep it
cp "$efi_file" "./release/"
echo "Copied $efi_file to ./release/$efi_basename (keeping original name)"
else
# Standard OneFileLinux.efi file, rename based on artifact
profile_name=${artifact_name#OneFileLinux-}
cp "$efi_file" "./release/OneFileLinux-$profile_name.efi"
echo "Copied $efi_file to ./release/OneFileLinux-$profile_name.efi"
fi
fi
done
fi
done
# Handle special case for custom builds that might have a different naming pattern
for artifact_dir in ./artifacts/OneFileLinux-custom*/; do
if [ -d "$artifact_dir" ]; then
echo "Processing custom artifact directory: $artifact_dir"
# Copy all EFI files as-is
for efi_file in "$artifact_dir"/*.efi; do
if [ -f "$efi_file" ]; then
cp "$efi_file" "./release/"
echo "Copied custom build file: $efi_file"
fi
done
fi
done
# Check what EFI files we have
echo "Release files:"
ls -la ./release/
# Create zip with all EFI files
cd release
zip -r OneFileLinux-release.zip *.efi
- name: Upload release package
uses: actions/upload-artifact@v4
with:
name: OneFileLinux-release
path: ./release/OneFileLinux-release.zip
# Create GitHub Release for v* tags
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
files: ./release/OneFileLinux-release.zip
name: "OneFileLinux ${{ github.ref_name }}"
draft: false
prerelease: ${{ contains(github.ref, '-rc') || contains(github.ref, '-beta') || contains(github.ref, '-alpha') }}
generate_release_notes: true