Skip to content
This repository was archived by the owner on May 25, 2025. It is now read-only.

📦️ Package macOS-x64 #178

📦️ Package macOS-x64

📦️ Package macOS-x64 #178

Workflow file for this run

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
name: "(A) 📦️ Package"
on:
workflow_dispatch:
inputs:
platform:
type: choice
required: true
default: Windows-x64
options:
- Windows-x64
- Linux-x64
- macOS-x64
beta:
type: boolean
required: false
default: false
runtime_artifact_workflow_run_id:
type: string
default: ""
required: false
workflow_call:
inputs:
platform:
type: string
default: Windows-x64
required: true
beta:
type: boolean
required: false
default: false
runtime_artifact_workflow_run_id:
type: string
default: ""
required: false
run-name: 📦️ Package ${{ inputs.platform }}
jobs:
main:
runs-on: ubuntu-latest
outputs:
run_id: ${{ github.run_id }}
steps:
- name: Checkout ${{ github.repository }}-runtime
uses: actions/checkout@v4
with:
repository: Floorp-Projects/Floorp-12-runtime
submodules: "recursive"
- name: Checkout Floorp
uses: actions/checkout@v4
with:
path: "floorp"
- uses: actions/setup-node@v4
with:
node-version: 22
- uses: denoland/setup-deno@v2
with:
deno-version: v2.x
- name: init zx
run: |
deno install -g -A npm:zx
- name: Setup Floorp
run: |
cd $GITHUB_WORKSPACE
cd ./floorp
deno install --allow-scripts
cd ..
- name: Setup 🪛
run: |
sudo apt install msitools -y
./mach --no-interactive bootstrap --application-choice browser_artifact_mode
- name: Write Versions
run: |
cd ./floorp
deno task build --write-version
cd ..
- name: Mach configure
run: |
if [ "${{inputs.platform}}" == "Windows-x64" ]; then
cp ./.github/workflows/mozconfigs/win64.mozconfig mozconfig
elif [ "${{inputs.platform}}" == "Linux-x64" ]; then
cp ./.github/workflows/mozconfigs/linux64.mozconfig mozconfig
else
cp ./.github/workflows/mozconfigs/macosx64-x86_64.mozconfig mozconfig
fi
# Copy Noraneko Branding
cp -r ./floorp/gecko/branding/* ./browser/branding/
mkdir floorp/gecko/config/autogenerated
echo "$(cat browser/config/version.txt)@$(cat floorp/gecko/config/version.txt)" >> floorp/gecko/config/autogenerated/version.txt
echo "$(cat browser/config/version_display.txt)@$(cat floorp/gecko/config/version_display.txt)" >> floorp/gecko/config/autogenerated/version_display.txt
echo "ac_add_options --with-version-file-path=floorp/gecko/config/autogenerated" >> mozconfig
# sed -i 's|ac_add_options --disable-maintenance-service|#ac_add_options --disable-maintenance-service|g' ./mozconfig
sed -i 's|ac_add_options --disable-updater||g' ./mozconfig
sed -i 's|ac_add_options --enable-unverified-updates||g' ./mozconfig
echo "ac_add_options --enable-release" >> mozconfig
echo "ac_add_options --disable-tests" >> mozconfig
echo "ac_add_options --enable-artifact-builds" >> mozconfig
echo "mk_add_options MOZ_OBJDIR=./obj-artifact-build-output" >> mozconfig
if [ "${{inputs.beta}}" == "true" ]; then
sed -i 's|MOZ_BRANDING_DIRECTORY=browser/branding/unofficial|MOZ_BRANDING_DIRECTORY=browser/branding/floorp-daylight|g' ./browser/confvars.sh
echo "ac_add_options --enable-update-channel=beta" >> mozconfig
else
sed -i 's|MOZ_BRANDING_DIRECTORY=browser/branding/unofficial|MOZ_BRANDING_DIRECTORY=browser/branding/floorp-official|g' ./browser/confvars.sh
echo "ac_add_options --enable-update-channel=release" >> mozconfig
fi
sed -i 's|ac_add_options --enable-chrome-format=flat||g' ./mozconfig
if [ "${{inputs.platform}}" == "macOS-x64" ]; then
# Extract macOS .dmg tools
mkdir -p ~/tools
curl -L https://firefox-ci-tc.services.mozilla.com/api/queue/v1/task/ceSQWV1AS76UlhYJ0_PfJQ/artifacts/public/build/dmg.tar.zst -o dmg.tar.zst
tar -I zstd -xf dmg.tar.zst -C ~/tools
sudo chmod 777 ~/tools/dmg
curl -L https://firefox-ci-tc.services.mozilla.com/api/queue/v1/task/N2SwCRLrRw2l-UWP4N7dhQ/artifacts/public/build/hfsplus.tar.zst -o hfsplus.tar.zst
tar -I zstd -xf hfsplus.tar.zst -C ~/tools
sudo chmod 777 ~/tools/hfsplus
# write mozconfig
echo "DMG_TOOL=$(echo ~/tools/dmg/dmg)" >> mozconfig
echo "HFS_TOOL=$(echo ~/tools/dmg/hfsplus)" >> mozconfig
echo "MKFSHFS=$(echo ~/tools/hfsplus/newfs_hfs)" >> mozconfig
fi
./mach configure
git apply --ignore-space-change --ignore-whitespace .github/patches/packaging/*.patch
- name: Possibly retrieve run ID if not provided
run: |
if [ -z "${{ inputs.runtime_artifact_workflow_run_id }}" ]; then
echo "RUNTIME_ARTIFACT_WORKFLOW_RUN_ID=false" >> $GITHUB_ENV
else
echo "RUNTIME_ARTIFACT_WORKFLOW_RUN_ID=${{ inputs.runtime_artifact_workflow_run_id }}" >> $GITHUB_ENV
fi
- name: Get Artifact Name
shell: zx --verbose {0}
env:
FORCE_COLOR: 3
BUILD_PLATFORM: ${{ inputs.platform }}
run: |
async function addToENV(name,value) {
await $`echo "${name}=${value}" >> $GITHUB_ENV`
}
switch (process.env.BUILD_PLATFORM) {
case "Windows-x64":
await addToENV("ARTIFACT_NAME","floorp-win-amd64-moz-artifact");
await addToENV("ARTIFACT_FROM_RELEASE_NAME","floorp-win-amd64-moz-artifact.zip");
await addToENV("OUTPUT_NAME","win-amd64");
await $`echo "INSTALLER_PATH=install/sea/*installer.exe" >> $GITHUB_ENV`;
await addToENV("OUTPUT_INSTALLER_NAME","floorp-win64-installer.exe");
break;
case "Linux-x64":
await addToENV("ARTIFACT_FROM_RELEASE_NAME","floorp-linux-amd64-moz-artifact.tar.xz");
await addToENV("OUTPUT_NAME","linux-amd64");
await $`echo "INSTALLER_PATH=floorp*tar.xz" >> $GITHUB_ENV`;
await addToENV("OUTPUT_INSTALLER_NAME","floorp-linux-amd64.tar.xz");
break;
case "macOS-x64":
await addToENV("ARTIFACT_NAME","floorp-mac-universal-moz-artifact-release");
await addToENV("ARTIFACT_FROM_RELEASE_NAME","floorp-mac-universal-moz-artifact-release.zip");
await addToENV("OUTPUT_NAME","mac-universal");
await $`echo "INSTALLER_PATH=floorp-*dmg" >> $GITHUB_ENV`;
await addToENV("OUTPUT_INSTALLER_NAME","floorp-macOS-universal.dmg");
break;
}
- name: Download mozilla artifact from Actions
if: ${{ env.RUNTIME_ARTIFACT_WORKFLOW_RUN_ID != 'false' }}
uses: actions/download-artifact@v4
with:
name: ${{ env.ARTIFACT_NAME }}
run-id: ${{ env.RUNTIME_ARTIFACT_WORKFLOW_RUN_ID }}
github-token: ${{github.token}}
repository: Floorp-Projects/Floorp-12-runtime
path: ~/downloads
- name: Download Mozilla Artifact from GitHub Releases
if: ${{ env.RUNTIME_ARTIFACT_WORKFLOW_RUN_ID == 'false' }}
run: |
mkdir -p ~/downloads
curl -L https://github.com/Floorp-Projects/Floorp-12-runtime/releases/latest/download/${{ env.ARTIFACT_FROM_RELEASE_NAME }} -o ~/downloads/${{ env.ARTIFACT_FROM_RELEASE_NAME }}
- name: Make Downloaded Artifact to Mozilla Artifact (Actions)
if: ${{ env.RUNTIME_ARTIFACT_WORKFLOW_RUN_ID != 'false' }}
run: |
mkdir -p ~/artifacts
cd ~/downloads
if [ "${{inputs.platform}}" == "Windows-x64" ]; then
zip -r ~/artifacts/floorp-win-amd64-moz-artifact.zip ./*
else
cp -r ~/downloads/* ~/artifacts
fi
cd $GITHUB_WORKSPACE
- name: Make Download Artifact to Mozilla Artifact (GitHub Releases)
if: ${{ env.RUNTIME_ARTIFACT_WORKFLOW_RUN_ID == 'false' }}
run: |
mkdir -p ~/artifacts
cd ~/downloads
if [ "${{inputs.platform}}" == "macOS-x64" ]; then
unzip floorp-mac-universal-moz-artifact-release.zip -d ~/artifacts
else
cp -r ~/downloads/* ~/artifacts
fi
cd $GITHUB_WORKSPACE
- name: Build Floorp
run: |
cd ./floorp
NODE_ENV='production' deno task build --release-build-before
cd ..
- name: Build
run: |
if [ "${{inputs.platform}}" == "Windows-x64" ]; then
MOZ_ARTIFACT_FILE=$(echo ~/artifacts/floorp-win-amd64-moz-artifact.zip) ./mach build
elif [ "${{inputs.platform}}" == "Linux-x64" ]; then
MOZ_ARTIFACT_FILE=$(echo ~/artifacts/floorp-linux-amd64-moz-artifact.tar.xz) ./mach build
elif [ "${{inputs.platform}}" == "macOS-x64" ]; then
MOZ_ARTIFACT_FILE="$(echo ~/artifacts/floorp-macOS-universal-moz-artifact.dmg):$(echo ~/artifacts/floorp-macOS.update_framework_artifacts.zip)" ./mach build
fi
- name: Inject Floorp
run: |
cd ./floorp
deno task build --release-build-after
# https://www.spinics.net/lists/git/msg391750.html
rsync -aL ../obj-artifact-build-output/dist/bin/ ../obj-artifact-build-output/dist/tmp__bin
rm -rf ../obj-artifact-build-output/dist/bin
mv ../obj-artifact-build-output/dist/tmp__bin ../obj-artifact-build-output/dist/bin
if [ "${{inputs.platform}}" == "macOS-x64" ]; then
for patch_file in ./scripts/git-patches/patches/*.patch; do
for resource_dir in ../obj-artifact-build-output/dist/*.app/Contents/Resources; do
if patch --follow-symlinks --dry-run -d "$resource_dir" -p1 < "$patch_file"; then
patch --follow-symlinks -d "$resource_dir" -p1 < "$patch_file"
else
echo "Dry-run failed for $patch_file in $resource_dir" >&2
exit 1
fi
done
done
else
git apply --reject ./scripts/git-patches/patches/*.patch --directory ../obj-artifact-build-output/dist/bin --unsafe-paths --check --apply
fi
cd ..
- name: Package noraneko
run: |
./mach package
- name: Prepare installer with codesigning and re-packaging
run: |
mkdir -p ~/noraneko-installer
if [ "${{inputs.platform}}" == "Windows-x64" ]; then
mv obj-*/dist/$INSTALLER_PATH ~/noraneko-installer/$OUTPUT_INSTALLER_NAME
elif [ "${{inputs.platform}}" == "Linux-x64" ]; then
mv obj-*/dist/$INSTALLER_PATH ~/noraneko-installer/$OUTPUT_INSTALLER_NAME
elif [ "${{inputs.platform}}" == "macOS-x64" ]; then
# Unpack DMG
mkdir -p ~/mac-code-signing/old ~/mac-code-signing/new
mv obj-*/dist/$INSTALLER_PATH ~/noraneko-installer/$OUTPUT_INSTALLER_NAME
./mach python -m mozbuild.action.unpack_dmg ~/noraneko-installer/$OUTPUT_INSTALLER_NAME ~/mac-code-signing/old
# Codesign
# Install apple-codesign
cargo install apple-codesign
echo ${{ secrets.APPLE_DEVELOPER_P12_BASE64 }} > floorp-cert.txt
base64 --decode floorp-cert.txt > floorpCert.p12
echo ${{ secrets.APPLE_DEVELOPER_P12_PASSWORD }} > floorpCertPassword.passwd
APP_FILE=$(find ~/mac-code-signing/old -name "*.app" -type d | head -n 1)
echo "Found app file: $APP_FILE"
# ./mach macos-sign can be used on macOS, We should use ubuntu-latest for this action.
# So, we need to use python script to codesign the app.
# ./mach macos-sign -v -r -c "release" -a "$APP_FILE" --rcodesign-p12-file floorpCert.p12 --rcodesign-p12-password-file floorpCertPassword.passwd
python ./floorp/scripts/codesign/mac/linux_codesign_macos_app.py "$APP_FILE" ./floorpCert.p12 ./floorpCertPassword.passwd
# Re-package DMG
if [ "${{inputs.beta}}" == "true" ]; then
DS_STORE_PATH="./floorp/.github/workflows/assets/mac/daylight/DS_Store"
BACKGROUND_PATH="./floorp/.github/workflows/assets/mac/daylight/background.tiff"
VOLUME_NAME="Floorp 12 Beta Installer"
else
DS_STORE_PATH="./floorp/.github/workflows/assets/mac/official/DS_Store"
BACKGROUND_PATH="./floorp/.github/workflows/assets/mac/official/background.tiff"
VOLUME_NAME="Floorp 12 Installer"
fi
./mach python -m mozbuild.action.make_dmg --dsstore $DS_STORE_PATH --background $BACKGROUND_PATH --volume-name "$VOLUME_NAME" ~/mac-code-signing/old ~/mac-code-signing/new/$OUTPUT_INSTALLER_NAME
echo '${{ secrets.APPLE_DEVELOPER_API_KEY_JSON }}' | jq '.' > ~/mac-code-signing/key.json
rcodesign notary-submit \
--api-key-file ~/mac-code-signing/key.json \
--wait \
~/mac-code-signing/new/$OUTPUT_INSTALLER_NAME
mv ~/mac-code-signing/new/$OUTPUT_INSTALLER_NAME ~/noraneko-installer/$OUTPUT_INSTALLER_NAME
fi
- name: Download artifact of MAR tools (Actions)
if: ${{ env.RUNTIME_ARTIFACT_WORKFLOW_RUN_ID != 'false' }}
uses: actions/download-artifact@v4
with:
pattern: "*dist-host"
run-id: ${{ env.RUNTIME_ARTIFACT_WORKFLOW_RUN_ID }}
github-token: ${{github.token}}
repository: Floorp-Projects/Floorp-12-runtime
path: obj-artifact-build-output/dist/host
merge-multiple: true
- name: Download artifact of MAR tools (GitHub Releases)
if: ${{ env.RUNTIME_ARTIFACT_WORKFLOW_RUN_ID == 'false' }}
run: |
curl -L https://github.com/Floorp-Projects/Floorp-12-runtime/releases/latest/download/${{ inputs.platform }}-dist-host.zip -o ~/downloads/${{ inputs.platform }}-dist-host.zip
unzip ~/downloads/${{ inputs.platform }}-dist-host.zip -d ./obj-artifact-build-output/dist/host
- name: Download artifact of binary for getting build information (Actions)
if: ${{ env.RUNTIME_ARTIFACT_WORKFLOW_RUN_ID != 'false' }}
uses: actions/download-artifact@v4
with:
pattern: "*application-ini"
run-id: ${{ env.RUNTIME_ARTIFACT_WORKFLOW_RUN_ID }}
github-token: ${{github.token}}
repository: Floorp-Projects/Floorp-12-runtime
path: ~/noraneko-dev
merge-multiple: true
- name: Download artifact of binary for getting build information (GiHub Releases)
if: ${{ env.RUNTIME_ARTIFACT_WORKFLOW_RUN_ID == 'false' }}
run: |
curl -L https://github.com/Floorp-Projects/Floorp-12-runtime/releases/latest/download/${{ inputs.platform }}-application-ini.zip -o ~/downloads/${{ inputs.platform }}-application-ini.zip
unzip ~/downloads/${{ inputs.platform }}-application-ini.zip -d ~/noraneko-dev
- name: Create MAR package
shell: zx --verbose {0}
env:
FORCE_COLOR: 3
run: |
const path_obj = await $`echo ./obj-*`;
await $`chmod +x ${path_obj}/dist/host/bin/mar`
await $`mkdir ~/noraneko-mar`
await $`awk -F "=" '/^Version/ {print $2}' "${os.homedir()}/noraneko-dev/nora-application.ini" > ~/noraneko-mar/version.txt`;
const version_txt = await $`cat ~/noraneko-mar/version.txt`
await $`touch "${path_obj}/dist/floorp/precomplete"`
const channelId = "${{ inputs.beta }}" === "true" ? "beta" : "release";
await $`MAR="${path_obj}/dist/host/bin/mar" MOZ_PRODUCT_VERSION=${version_txt} MAR_CHANNEL_ID=${channelId} ./tools/update-packaging/make_full_update.sh ~/noraneko-mar/floorp-${{ env.OUTPUT_NAME }}-full.mar "${path_obj}/dist/floorp"`;
await $`cp floorp/gecko/config/version.txt ~/noraneko-mar/noraneko_version.txt`
await $`cp floorp/_dist/buildid2 ~/noraneko-mar/noraneko_buildid.txt`
const noraneko_version_txt = await $`cat ~/noraneko-mar/noraneko_version.txt`
await $`echo "${version_txt}@${noraneko_version_txt}" > ~/noraneko-mar/version_display.txt`
await $`shasum --algorithm 512 ~/noraneko-mar/floorp-${{ env.OUTPUT_NAME }}-full.mar | cut -c 1-128 > ~/noraneko-mar/mar_shasum.txt`
await $`stat --format "%s" ~/noraneko-mar/floorp-${{ env.OUTPUT_NAME }}-full.mar > ~/noraneko-mar/mar_size.txt`
await $`awk -F "=" '/BuildID/ {print $2}' "${os.homedir()}/noraneko-dev/nora-application.ini" > ~/noraneko-mar/buildid.txt`
await $`mkdir ~/noraneko-publish`
const version_display = (await $`cat ~/noraneko-mar/version_display.txt`);
const version = (await $`cat ~/noraneko-mar/version.txt`);
const noraneko_version = (await $`cat ~/noraneko-mar/noraneko_version.txt`);
const noraneko_buildid = (await $`cat ~/noraneko-mar/noraneko_buildid.txt`);
const mar_size = (await $`cat ~/noraneko-mar/mar_size.txt`);
const mar_shasum = (await $`cat ~/noraneko-mar/mar_shasum.txt`);
const buildid = (await $`cat ~/noraneko-mar/buildid.txt`);
console.log(`Version Display: ${version_display}`);
console.log(`Version: ${version}`);
console.log(`Noraneko Version: ${noraneko_version}`);
console.log(`Noraneko BuildID: ${noraneko_buildid}`);
console.log(`MAR Size: ${mar_size}`);
console.log(`MAR SHA-512: ${mar_shasum}`);
console.log(`BuildID: ${buildid}`);
const json = {
version_display: version_display.toString().trim(),
version: version.toString().trim(),
noraneko_version: noraneko_version.toString().trim(),
noraneko_buildid: noraneko_buildid.toString().trim(),
mar_size: parseInt(mar_size.toString().trim()),
mar_shasum: mar_shasum.toString().trim(),
buildid: buildid.toString().trim()
};
await fs.writeJson(os.homedir()+"/noraneko-publish/meta.json", json, { spaces: 2 });
await $`cat ~/noraneko-publish/meta.json`
await $`echo "Meta JSON file content has been created and saved successfully."`
await $`cp ~/noraneko-mar/*.mar ~/noraneko-publish`;
- name: Publish dist 🎁
uses: actions/upload-artifact@v4
with:
name: noraneko-${{ env.OUTPUT_NAME }}-installer
path: ~/noraneko-installer/*
compression-level: 9
- name: Publish MAR 🎁
uses: actions/upload-artifact@v4
with:
name: noraneko-${{ env.OUTPUT_NAME }}-mar-full
path: ~/noraneko-publish/*