Skip to content

Commit ce456b6

Browse files
macOS: CI/CD adds macOS 15 Intel build server
Two important changes: - Use two build servers: Intel and ARM instead of a single ARM build server. Reason: Intel processor stuck on the 'macos-15-intel' runner as the last macOS runner that supported Intel architecture. Arm processor still uses the 'macos-latest' runner. Brew install --cask Replace fpc-laz with fpc Reason: fpc-laz will be disabled/removed on September 1, 2026. Homebrew/homebrew-cask@3648170 Fpc should now be used as a replacement. Note: Brew 'Lazarus' has not been updated due to an issue. The solution is to use 'fpc' to build Lazarus from source code. And to build the tracker editor.
1 parent 8b2d945 commit ce456b6

File tree

1 file changed

+173
-42
lines changed

1 file changed

+173
-42
lines changed

.github/workflows/cicd_macos.yaml

Lines changed: 173 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
1+
# CI/CD workflow for macOS systems to build bittorrent tracker editor app
2+
# Uses GitHub Actions macOS runners to build the app for both Apple silicon (aarch64) and Intel Mac (x86_64)
3+
# Then create a Universal binary using lipo tool.
4+
# Finally create a dmg file for end user distribution.
5+
# The build also codesign and notarize the dmg file if the required Apple developer certificate
6+
# and notarization credentials are present in the GitHub secrets.
7+
# The build is triggered on push, pull request, manual workflow dispatch and every 6 months cron job.
8+
#
9+
# macos-15-intel runner is used to build the x86_64 version.
10+
# macos-latest runner is used to build the aarch64 version and also to create the Universal binary dmg file.
11+
# The build uses Free Pascal Compiler (FPC) and Lazarus IDE to build the app.
12+
#
13+
# macos-15-intel runner is the last macOS runner that supports Intel architecture.
14+
# Newer macOS runners only support Apple silicon (aarch64) architecture.
15+
# Keep supporting Intel architecture build while there runners are still available.
16+
#
17+
# Must use macOS ditto tool to create zip files.
18+
# Using zip command creates zip files that missing some metadata required for macOS apps.
19+
20+
121
name: CI/CD on macOS systems.
222

323
permissions:
@@ -11,31 +31,28 @@ on:
1131
schedule:
1232
- cron: "0 0 1 1/6 *"
1333

34+
env:
35+
MACOS_APP: enduser/trackereditor.app
36+
PROGRAM_NAME_WITH_PATH: 'enduser/trackereditor'
37+
BUILD_WITH_CERTIFICATE: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }}
38+
PROJECT_LPI: source/project/tracker_editor/trackereditor.lpi
39+
RELEASE_DMG_FILE: trackereditor_macOS_notarized_universal_binary.dmg
40+
# Copied the latest Lazarus source code from: https://sourceforge.net/projects/lazarus/files/Lazarus%20Zip%20_%20GZip/
41+
LAZARUS_URL_TAR_GZ: "https://github.com/GerryFerdinandus/bittorrent-tracker-editor/releases/download/V1.32.0/lazarus.tar.gz"
42+
1443
jobs:
15-
build:
44+
build_aarch64: # Build for Apple silicon Mac architecture
1645
runs-on: macos-latest
1746
timeout-minutes: 60
18-
env:
19-
MACOS_APP: enduser/trackereditor.app
20-
PROGRAM_NAME_WITH_PATH: 'enduser/trackereditor'
21-
BUILD_WITH_CERTIFICATE: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }}
22-
PROJECT_LPI: source/project/tracker_editor/trackereditor.lpi
23-
RELEASE_DMG_FILE: trackereditor_macOS_notarized_universal_binary.dmg
24-
# Copied the latest Lazarus source code from: https://sourceforge.net/projects/lazarus/files/Lazarus%20Zip%20_%20GZip/
25-
LAZARUS_URL_TAR_GZ: "https://github.com/GerryFerdinandus/bittorrent-tracker-editor/releases/download/V1.32.0/lazarus.tar.gz"
26-
2747
steps:
28-
- uses: actions/checkout@v4
48+
- uses: actions/checkout@v5
2949
with:
3050
submodules: true
3151

3252
- name: Install Free Pascal Compiler (FPC) multi arch version for macOS x86_64 and aarch64
33-
run: brew install --cask fpc-laz
53+
run: brew install fpc
3454
shell: bash
3555

36-
- name: Install Create dmg
37-
run: brew install create-dmg
38-
3956
- name: Download Lazarus source code into temp folder
4057
run: |
4158
#Download lazarus source code. Directory 'lazarus' will be created in the temp folder.
@@ -59,25 +76,13 @@ jobs:
5976
- name: Build trackereditor app for Apple silicon (aarch64)
6077
run: |
6178
lazbuild --build-all --build-mode=Release --widgetset=cocoa --cpu=aarch64 ${{ env.PROJECT_LPI }}
62-
mv ${{ env.PROGRAM_NAME_WITH_PATH }} ${{ env.PROGRAM_NAME_WITH_PATH }}-aarch64
6379
shell: bash
6480

65-
- name: Build trackereditor app for Intel Mac version (x86_64)
66-
run: |
67-
lazbuild --build-all --build-mode=Release --widgetset=cocoa --cpu=x86_64 ${{ env.PROJECT_LPI }}
68-
mv ${{ env.PROGRAM_NAME_WITH_PATH }} ${{ env.PROGRAM_NAME_WITH_PATH }}-x86_64
69-
shell: bash
70-
71-
- name: Create a Universal macOS binary from aarch64 and x86_64
72-
run: |
73-
# Create a new Universal macOS binary
74-
lipo -create -output ${{ env.PROGRAM_NAME_WITH_PATH }} ${{ env.PROGRAM_NAME_WITH_PATH }}-aarch64 ${{ env.PROGRAM_NAME_WITH_PATH }}-x86_64
75-
76-
# Remove these extra binary build. Not needed any more.
77-
rm -f ${{ env.PROGRAM_NAME_WITH_PATH }}-*
81+
- name: Test App SSL connection
82+
run: open "${{ env.PROGRAM_NAME_WITH_PATH }}" --args -TEST_SSL
7883
shell: bash
7984

80-
- name: Extract latest program version from metainfo and update the Info.plist with it
85+
- name: Set correct version number in macOS .app bundle Info.plist from metainfo xml file
8186
env:
8287
METAINFO_FILE: metainfo/io.github.gerryferdinandus.bittorrent-tracker-editor.metainfo.xml
8388
run: |
@@ -86,17 +91,10 @@ jobs:
8691
plutil -replace CFBundleShortVersionString -string $TRACKER_EDITOR_VERSION ${{ env.MACOS_APP }}/Contents/Info.plist
8792
shell: bash
8893

89-
- name: Move program and icon into macOS .app
94+
- name: Create and set app icon in macOS .app bundle
9095
env:
9196
ICON_FILE: 'metainfo/io.github.gerryferdinandus.bittorrent-tracker-editor.png'
9297
run: |
93-
PROGRAM_NAME_ONLY=$(basename -- "${{ env.PROGRAM_NAME_WITH_PATH }}")
94-
95-
# ------ Move program to app
96-
# remove the previeus app version
97-
rm -f "${{ env.MACOS_APP }}/Contents/MacOS/${PROGRAM_NAME_ONLY}"
98-
# copy the program to the app version.
99-
mv -f "${{ env.PROGRAM_NAME_WITH_PATH }}" "${{ env.MACOS_APP }}/Contents/MacOS"
10098
10199
# ------ Create icon set and move it into the app
102100
iconset_folder="temp_folder.iconset"
@@ -120,7 +118,139 @@ jobs:
120118
plutil -insert CFBundleIconFile -string "iconfile" "${{ env.MACOS_APP }}/Contents/Info.plist"
121119
shell: bash
122120

123-
- name: Check CPU type generated by Lazbuild
121+
- name: Zip the macOS .app bundle for artifact upload
122+
run: ditto -c -k enduser/trackereditor.app enduser/trackereditor_app.zip
123+
shell: bash
124+
125+
- name: Rename built -aarch64 binary for artifact upload
126+
run: |
127+
mv ${{ env.PROGRAM_NAME_WITH_PATH }} ${{ env.PROGRAM_NAME_WITH_PATH }}-aarch64
128+
ditto -c -k ${{ env.PROGRAM_NAME_WITH_PATH }}-aarch64 ${{ env.PROGRAM_NAME_WITH_PATH }}-aarch64.zip
129+
shell: bash
130+
131+
- name: Upload Artifact.
132+
uses: actions/upload-artifact@v4
133+
with:
134+
name: artifact-aarch64
135+
# Include both the zipped universal app bundle and the aarch64 binary zip
136+
path: enduser/*.zip
137+
if-no-files-found: error
138+
139+
build_x86_64: # Build for Intel Mac architecture
140+
runs-on: macos-15-intel
141+
timeout-minutes: 60
142+
steps:
143+
- uses: actions/checkout@v5
144+
with:
145+
submodules: true
146+
147+
- name: Install Free Pascal Compiler (FPC) multi arch version for macOS x86_64 and aarch64
148+
run: brew install fpc
149+
shell: bash
150+
151+
- name: Download Lazarus source code into temp folder
152+
run: |
153+
#Download lazarus source code. Directory 'lazarus' will be created in the temp folder.
154+
cd ${RUNNER_TEMP}
155+
curl -L -O ${{ env.LAZARUS_URL_TAR_GZ }}
156+
tar -xzf *.tar.gz
157+
shell: bash
158+
159+
- name: Build lazbuild from Lazarus source code
160+
run: |
161+
# make lazbuild and put the link with extra parameter in the temp folder.
162+
LAZARUS_DIR=${RUNNER_TEMP}/lazarus
163+
cd "$LAZARUS_DIR"
164+
make lazbuild
165+
echo "$LAZARUS_DIR/lazbuild --primary-config-path=$LAZARUS_DIR --lazarusdir=$LAZARUS_DIR \$*" > ${RUNNER_TEMP}/lazbuild
166+
chmod +x ${RUNNER_TEMP}/lazbuild
167+
# Add lazbuild to the PATH variable. So it can be used in the next steps.
168+
echo ${RUNNER_TEMP} >> $GITHUB_PATH
169+
shell: bash
170+
171+
- name: Build trackereditor app for Intel Mac version (x86_64)
172+
run: |
173+
lazbuild --build-all --build-mode=Release --widgetset=cocoa --cpu=x86_64 ${{ env.PROJECT_LPI }}
174+
shell: bash
175+
176+
- name: Test App SSL connection
177+
run: open "${{ env.PROGRAM_NAME_WITH_PATH }}" --args -TEST_SSL
178+
shell: bash
179+
180+
- name: Rename built -x86_64 binary for artifact upload
181+
run: |
182+
mv ${{ env.PROGRAM_NAME_WITH_PATH }} ${{ env.PROGRAM_NAME_WITH_PATH }}-x86_64
183+
ditto -c -k ${{ env.PROGRAM_NAME_WITH_PATH }}-x86_64 ${{ env.PROGRAM_NAME_WITH_PATH }}-x86_64.zip
184+
shell: bash
185+
186+
- name: Upload Artifact.
187+
uses: actions/upload-artifact@v4
188+
with:
189+
name: artifact-x86_64
190+
path: enduser/*.zip
191+
if-no-files-found: error
192+
193+
194+
create_universal_macOS_binary: # Create Universal binary from aarch64 and x86_64 builds
195+
runs-on: macos-latest
196+
timeout-minutes: 60
197+
198+
needs:
199+
- build_aarch64
200+
- build_x86_64
201+
202+
steps:
203+
- name: Install create-dmg tool
204+
run: brew install create-dmg
205+
shell: bash
206+
207+
- name: Download build artifacts from previous jobs
208+
uses: actions/download-artifact@v5
209+
with:
210+
path: enduser/
211+
merge-multiple: true
212+
213+
- name: Display the downloaded artifact files
214+
run: ls -R enduser/
215+
shell: bash
216+
217+
- name: Unzip all the artifact files
218+
run: |
219+
ditto -xk enduser/trackereditor_app.zip enduser/trackereditor.app
220+
ditto -xk ${{ env.PROGRAM_NAME_WITH_PATH }}-x86_64.zip enduser/
221+
ditto -xk ${{ env.PROGRAM_NAME_WITH_PATH }}-aarch64.zip enduser/
222+
# Remove the zip files after extraction
223+
rm -f enduser/*.zip
224+
shell: bash
225+
226+
- name: Display the downloaded artifact files after unzip
227+
run: ls -R enduser/
228+
shell: bash
229+
230+
- name: Create a Universal macOS binary from aarch64 and x86_64
231+
run: |
232+
# Create Universal binary using lipo tool
233+
lipo -create -output ${{ env.PROGRAM_NAME_WITH_PATH }} ${{ env.PROGRAM_NAME_WITH_PATH }}-aarch64 ${{ env.PROGRAM_NAME_WITH_PATH }}-x86_64
234+
235+
# Remove the previous architecture specific binaries
236+
rm -f ${{ env.PROGRAM_NAME_WITH_PATH }}-*
237+
shell: bash
238+
239+
- name: Replace the macOS .app bundle binary with the Universal binary
240+
run: |
241+
PROGRAM_NAME_ONLY=$(basename -- "${{ env.PROGRAM_NAME_WITH_PATH }}")
242+
# remove the previous app (symbolic link)
243+
rm -f "${{ env.MACOS_APP }}/Contents/MacOS/${PROGRAM_NAME_ONLY}"
244+
# copy the program to the app version.
245+
mv -f "${{ env.PROGRAM_NAME_WITH_PATH }}" "${{ env.MACOS_APP }}/Contents/MacOS"
246+
ls -l "${{ env.MACOS_APP }}/Contents/MacOS/"
247+
shell: bash
248+
249+
- name: Display the enduser/ folder contents
250+
run: ls -R enduser/
251+
shell: bash
252+
253+
- name: Verify the Universal binary architectures
124254
run: |
125255
lipo -archs "${{ env.MACOS_APP }}"/Contents/MacOS/trackereditor
126256
lipo -archs "${{ env.MACOS_APP }}"/Contents/MacOS/trackereditor | grep -Fq x86_64
@@ -160,11 +290,12 @@ jobs:
160290
/usr/bin/codesign --timestamp --force --options runtime --sign "$MACOS_CERTIFICATE_NAME" "${{ env.MACOS_APP }}"
161291
shell: bash
162292

293+
- name: Display the enduser/ folder contents
294+
run: ls -R enduser/
295+
shell: bash
296+
163297
- name: Create dmg file from the enduser/ folder
164298
run: |
165-
# Remove all txt file. There are not needed.
166-
rm -f enduser/*.txt
167-
168299
# Build dmg image. https://github.com/create-dmg/create-dmg
169300
create-dmg \
170301
--volname "bittorrent-tracker-editor" \

0 commit comments

Comments
 (0)