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

📦️ Package Windows-x64 #211

📦️ Package Windows-x64

📦️ Package Windows-x64 #211

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
shell: zx --verbose {0}
env:
FORCE_COLOR: 3
BUILD_PLATFORM: ${{ inputs.platform }}
IS_BETA: ${{ inputs.beta }}
run: |
// Copy appropriate mozconfig based on platform
const mozconfigs = {
'Windows-x64': './.github/workflows/mozconfigs/win64.mozconfig',
'Linux-x64': './.github/workflows/mozconfigs/linux64.mozconfig',
'macOS-x64': './.github/workflows/mozconfigs/macosx64-x86_64.mozconfig'
};
await $`cp ${mozconfigs[process.env.BUILD_PLATFORM]} mozconfig`;
// Copy Noraneko Branding
await $`cp -r ./floorp/gecko/branding/* ./browser/branding/`;
// Create and setup version files
await $`mkdir -p floorp/gecko/config/autogenerated`;
const version = await $`cat browser/config/version.txt`;
const geckoVersion = await $`cat floorp/gecko/config/version.txt`;
await $`echo "${version}@${geckoVersion}" > floorp/gecko/config/autogenerated/version.txt`;
const versionDisplay = await $`cat browser/config/version_display.txt`;
const geckoVersionDisplay = await $`cat floorp/gecko/config/version_display.txt`;
await $`echo "${versionDisplay}@${geckoVersionDisplay}" > floorp/gecko/config/autogenerated/version_display.txt`;
// Configure for beta or release
// Helper function to run sed command
const sedReplace = async (pattern, replacement, file) => {
console.log(`Replacing ${pattern} with ${replacement} in ${file}`);
await $`sed -i 's|${pattern}|${replacement}|g' ${file}`;
};
// Helper function to add mozconfig options
const addMozConfig = async (option) => {
console.log(`Adding ${option} to mozconfig`);
await $`echo "ac_add_options ${option}" >> mozconfig`;
};
// Append base configuration to mozconfig
const baseConfig = [
'--with-version-file-path=floorp/gecko/config/autogenerated',
'--enable-release',
'--disable-tests',
'--enable-artifact-builds'
];
for (const option of baseConfig) {
await $`echo "ac_add_options ${option}" >> mozconfig`;
}
// Remove mozconfig options for flat chrome and branding
const removeConfig = [
'--disable-updater',
'--enable-chrome-format=flat',
'--enable-unverified-updates',
];
for (const option of removeConfig) {
// sed -i 's|ac_add_options --disable-updater||g' ./mozconfig
// sed -i 's|ac_add_options --enable-unverified-updates||g' ./mozconfig
// await $`sed -i 's|ac_add_options --enable-chrome-format=flat||g' ./mozconfig`;
$`sed -i '/ac_add_options ${option}/d' mozconfig`;
}
// Common paths/files
const confvarsPath = './browser/confvars.sh';
const updateUtilsPath = './toolkit/modules/UpdateUtils.sys.mjs';
if (process.env.IS_BETA === 'true') {
// Beta configuration
await sedReplace(
'MOZ_BRANDING_DIRECTORY=browser/branding/unofficial',
'MOZ_BRANDING_DIRECTORY=browser/branding/floorp-daylight',
confvarsPath
);
await addMozConfig('--enable-update-channel=beta');
await addMozConfig('--with-branding=browser/branding/floorp-daylight');
// Set update URL based on platform
const baseUrl = 'https://github.com/Floorp-Projects/Floorp-12/releases/download/beta/';
const platformUrls = {
'Windows-x64': `${baseUrl}WINNT_x86_64-msvc-x64.`,
'Linux-x64': `${baseUrl}Linux_x86_64.`,
'macOS-x64': `${baseUrl}Darwin_x86_64.`
};
if (platformUrls[process.env.BUILD_PLATFORM]) {
await sedReplace(
'REPLACE_THIS_NORA_UPDATE_HOST_TARGET_PLACEHOLDER',
platformUrls[process.env.BUILD_PLATFORM],
updateUtilsPath
);
} else {
console.error('Unsupported platform: ' + process.env.BUILD_PLATFORM);
}
} else {
// Release configuration
await sedReplace(
'MOZ_BRANDING_DIRECTORY=browser/branding/unofficial',
'MOZ_BRANDING_DIRECTORY=browser/branding/floorp-official',
confvarsPath
);
await addMozConfig('--enable-update-channel=release');
await addMozConfig('--with-branding=browser/branding/floorp-official');
// Read version from version_display.txt to use in update URLs
const versionFromFile = (await $`cat ./browser/config/version_display.txt`).toString().trim();
console.log(`Using version from file: ${versionFromFile}`);
// Set update URL based on platform
const baseUrl = `https://floorp-update.ablaze.one/browser/${versionFromFile}/`;
const platformUrls = {
'Windows-x64': `${baseUrl}WINNT/x86_64/`,
'Linux-x64': `${baseUrl}Linux/x86_64/`,
'macOS-x64': `${baseUrl}Darwin/x86_64/`
};
if (platformUrls[process.env.BUILD_PLATFORM]) {
await sedReplace(
'REPLACE_THIS_NORA_UPDATE_HOST_TARGET_PLACEHOLDER',
platformUrls[process.env.BUILD_PLATFORM],
updateUtilsPath
);
} else {
console.error('Unsupported platform: ' + process.env.BUILD_PLATFORM);
}
}
await $`echo "mk_add_options MOZ_OBJDIR=./obj-artifact-build-output" >> mozconfig`;
// Special configuration for macOS
if (process.env.BUILD_PLATFORM === 'macOS-x64') {
await $`mkdir -p ~/tools`;
// Download and extract DMG tools
await $`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`;
await $`tar -I zstd -xf dmg.tar.zst -C ~/tools`;
await $`sudo chmod 777 ~/tools/dmg`;
await $`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`;
await $`tar -I zstd -xf hfsplus.tar.zst -C ~/tools`;
await $`sudo chmod 777 ~/tools/hfsplus`;
// Add macOS specific mozconfig options
const macConfig = [
`DMG_TOOL=${os.homedir()}/tools/dmg/dmg`,
`HFS_TOOL=${os.homedir()}/tools/dmg/hfsplus`,
`MKFSHFS=${os.homedir()}/tools/hfsplus/newfs_hfs`
];
for (const option of macConfig) {
await $`echo "${option}" >> mozconfig`;
}
}
// Run configure and apply patches
await $`./mach configure`;
await $`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 -v -r -c "release" \
-a "$APP_FILE" \
--rcodesign-p12-file floorpCert.p12 \
--rcodesign-p12-password-file 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 Daylight 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 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/*