gh-9836: Finish the MAR signing workflow (gh-13216)

This commit is contained in:
mr. m
2026-04-13 15:49:24 +02:00
committed by GitHub
parent 7bbbdd3c4b
commit adc8c92816
6 changed files with 113 additions and 66 deletions

View File

@@ -126,7 +126,7 @@ jobs:
permissions:
contents: write
name: Generate build data
runs-on: blacksmith-2vcpu-ubuntu-2404
runs-on: ubuntu-latest
needs: buildid
outputs:
build_date: ${{ steps.data.outputs.builddate }}
@@ -359,7 +359,7 @@ jobs:
name: AppImage build - Linux ${{ matrix.arch }}
permissions:
contents: write
runs-on: blacksmith-2vcpu-ubuntu-2404
runs-on: ubuntu-latest
strategy:
matrix:
arch: [x86_64, aarch64]
@@ -439,7 +439,7 @@ jobs:
path: ./dist/zen-${{ matrix.arch }}.AppImage.zsync
stop-self-hosted:
runs-on: blacksmith-2vcpu-ubuntu-2404
runs-on: ubuntu-latest
needs: [windows-step-3, linux]
if: always()
steps:
@@ -505,10 +505,22 @@ jobs:
run: |
git clone https://github.com/zen-browser/windows-binaries.git .github/workflows/object --depth 1
- name: Sign MAR files
env:
SIGNMAR: ${{ github.workspace }}/linux-bin-x86_64/signmar
ZEN_MAR_SIGNING_PASSWORD: ${{ secrets.ZEN_MAR_SIGNING_PASSWORD }}
ZEN_SIGNING_CERT_PEM_BASE64: ${{ secrets.ZEN_SIGNING_CERT_PEM_BASE64 }}
ZEN_SIGNING_PRIVATE_KEY_PEM_BASE64: ${{ secrets.ZEN_SIGNING_PRIVATE_KEY_PEM_BASE64 }}
run: |
bash scripts/mar_sign.sh -s
- name: Copy update manifests
env:
RELEASE_BRANCH: ${{ inputs.update_branch }}
run: |
# IMPORTANT: If changing any of these names,
# make sure to also update the paths in the mar_sign.sh script
cd updates-server
mkdir -p updates
cp -a ../linux_update_manifest_x86_64/. updates/
@@ -602,7 +614,7 @@ jobs:
permissions: write-all
name: Prepare Flatpak
needs: [release, linux, build-data]
runs-on: blacksmith-2vcpu-ubuntu-2404
runs-on: ubuntu-latest
steps:
- name: Checkout Flatpak repository
@@ -661,7 +673,7 @@ jobs:
permissions: write-all
name: Release Flatpak
needs: [prepare-flatpak, build-data]
runs-on: blacksmith-2vcpu-ubuntu-2404
runs-on: ubuntu-latest
steps:
- name: Checkout Flatpak repository

View File

@@ -153,15 +153,6 @@ jobs:
mv dist/zen-*.tar.xz "zen.linux-${{ matrix.arch }}.tar.xz"
mv dist/output.mar linux${{ matrix.arch == 'aarch64' && '-aarch64' || '' }}.mar
- name: Sign MAR
env:
SIGNMAR: engine/obj-${{ matrix.arch == 'aarch64' && 'aarch64-unknown' || 'x86_64-pc' }}-linux-gnu/dist/bin/signmar
ZEN_MAR_SIGNING_PASSWORD: ${{ secrets.ZEN_MAR_SIGNING_PASSWORD }}
ZEN_SIGNING_CERT_PEM_BASE64: ${{ secrets.ZEN_SIGNING_CERT_PEM_BASE64 }}
ZEN_SIGNING_PRIVATE_KEY_PEM_BASE64: ${{ secrets.ZEN_SIGNING_PRIVATE_KEY_PEM_BASE64 }}
run: |
bash scripts/mar_sign.sh -s ./linux${{ matrix.arch == 'aarch64' && '-aarch64' || '' }}.mar
- name: Upload build artifact (binary)
uses: actions/upload-artifact@v4
with:
@@ -182,3 +173,11 @@ jobs:
retention-days: 5
name: linux_update_manifest_${{ matrix.arch }}
path: ./dist/update
- name: Upload linux bin
if: ${{ matrix.arch == 'x86_64' }}
uses: actions/upload-artifact@v4
with:
retention-days: 2
name: linux-bin-x86_64
path: engine/obj-x86_64-pc-linux-gnu/dist/bin/

View File

@@ -247,15 +247,6 @@ jobs:
npm run package -- --verbose
mv ./dist/output.mar ./macos.mar
- name: Sign MAR
env:
SIGNMAR: engine/obj-x86_64-apple-darwin/dist/bin/signmar
ZEN_MAR_SIGNING_PASSWORD: ${{ secrets.ZEN_MAR_SIGNING_PASSWORD }}
ZEN_SIGNING_CERT_PEM_BASE64: ${{ secrets.ZEN_SIGNING_CERT_PEM_BASE64 }}
ZEN_SIGNING_PRIVATE_KEY_PEM_BASE64: ${{ secrets.ZEN_SIGNING_PRIVATE_KEY_PEM_BASE64 }}
run: |
bash scripts/mar_sign.sh -s ./macos.mar
- name: Upload build artifact (.mar)
uses: actions/upload-artifact@v4
with:

View File

@@ -281,21 +281,11 @@ jobs:
mv ./dist/output.mar windows${{ matrix.arch == 'aarch64' && '-arm64' || '' }}.mar
mv ./dist/zen.installer.exe ./zen.installer${{ matrix.arch == 'aarch64' && '-arm64' || '' }}.exe
- name: Sign MAR
if: ${{ !inputs.generate-gpo }}
env:
SIGNMAR: engine/obj-${{ matrix.arch }}-pc-windows-msvc/dist/bin/signmar
ZEN_MAR_SIGNING_PASSWORD: ${{ secrets.ZEN_MAR_SIGNING_PASSWORD }}
ZEN_SIGNING_CERT_PEM_BASE64: ${{ secrets.ZEN_SIGNING_CERT_PEM_BASE64 }}
ZEN_SIGNING_PRIVATE_KEY_PEM_BASE64: ${{ secrets.ZEN_SIGNING_PRIVATE_KEY_PEM_BASE64 }}
run: |
bash scripts/mar_sign.sh -s ./windows${{ matrix.arch == 'aarch64' && '-arm64' || '' }}.mar
- name: Upload artifact (PGO)
uses: actions/upload-artifact@v4
if: ${{ inputs.generate-gpo && matrix.arch == 'x86_64' }}
with:
retention-days: 5
retention-days: 2
name: ${{ matrix.arch == 'aarch64' && 'arm64' || matrix.arch }}-${{ inputs.profile-data-path-archive }}
path: ./zen.win64-pgo-stage-1.zip
@@ -322,14 +312,6 @@ jobs:
name: windows-x64-obj-${{ matrix.arch == 'aarch64' && 'arm64' || matrix.arch }}
path: obj-${{ matrix.arch }}-pc-windows-msvc
- name: Upload artifact (if Twilight branch, binary)
if: ${{ inputs.release-branch == 'twilight' && !inputs.generate-gpo }}
uses: actions/upload-artifact@v4
with:
retention-days: 5
name: zen.win-${{ matrix.arch == 'aarch64' && 'arm64' || matrix.arch }}.zip
path: ./zen.win-${{ matrix.arch == 'aarch64' && 'arm64' || matrix.arch }}.zip
- name: Upload artifact (if Twilight branch, installer)
if: ${{ inputs.release-branch == 'twilight' && !inputs.generate-gpo }}
uses: actions/upload-artifact@v4

View File

@@ -84,7 +84,7 @@ create_nss_config_dir() {
openssl pkcs12 -export \
-inkey "$CERT_PATH_DIR/private_key.pem" \
-in "$CERT_PATH_DIR/cert.pem" \
-name "mar_cert" \
-name "mar_sig" \
-passout pass:"$ZEN_MAR_SIGNING_PASSWORD" \
-out "$CERT_PATH_DIR/private_key.p12"
@@ -105,19 +105,58 @@ cleanup_certs() {
rm -f "$CERT_PATH_DIR/cert.pem"
}
sign_mar() {
local mar_file="$1"
if [ -z "$mar_file" ]; then
echo "Error: .mar file path is required. Usage: $0 -s <mar_file>" >&2
exit 1
fi
if [ ! -f "$mar_file" ]; then
echo "Error: .mar file not found at $mar_file" >&2
update_manifests() {
mar_file=$(basename "$1")
if [[ "$mar_file" == "linux.mar" ]]; then
manifest="linux_update_manifest_x86_64"
elif [[ "$mar_file" == "linux-aarch64.mar" ]]; then
manifest="linux_update_manifest_aarch64"
elif [[ "$mar_file" == "windows.mar" ]]; then
manifest=".github/workflows/object/windows-x64-signed-x86_64/update_manifest"
if [ ! -f "$manifest" ]; then
manifest="windows_update_manifest_x86_64"
fi
elif [[ "$mar_file" == "windows-arm64.mar" ]]; then
manifest=".github/workflows/object/windows-x64-signed-arm64/update_manifest"
if [ ! -f "$manifest" ]; then
manifest="windows_update_manifest_arm64"
fi
elif [[ "$mar_file" == "macos.mar" ]]; then
manifest="macos_update_manifest"
else
echo "Unknown MAR file name format: $mar_file. Skipping manifest update." >&2
exit 1
fi
# There can be any update.xml file, lets just recursively search for the one
manifest_files=$(find "$manifest" -type f -name "update.xml")
for manifest_file in $manifest_files; do
# Example manifest:
# <update type="minor" displayVersion="..." appVersion="..." platformVersion="..." buildID="...">
# <patch type="complete" URL="..." hashFunction="sha512" hashValue="..." size="..."/>
# </update>
# </updates>
# When signing the mar, hashValue and size will change, so we need to update the manifest with
# the new values. We can get the new values by running "mar -i signed_mar_file.mar"
echo "Updating manifest $manifest_file with new hash and size for $mar_file"
size=$(wc -c < "$1" | tr -d ' ')
hashValue=$(sha512sum "$1" | awk '{print $1}')
# Update the manifest with the new values. We can use sed to do this.
# We need to find the line that contains the URL of the mar file, and update the hashValue and size attributes in the same <patch> element.
old_hashValue=$(grep -oP 'hashValue="\K[^"]+' "$manifest_file")
old_size=$(grep -oP 'size="\K[^"]+' "$manifest_file")
if [ -z "$old_hashValue" ] || [ -z "$old_size" ]; then
echo "Could not find old hashValue or size in manifest. Skipping manifest update." >&2
exit 1
fi
echo "Old hashValue: $old_hashValue, Old size: $old_size"
echo "New hashValue: $hashValue, New size: $size"
sed -i.bak "s/hashValue=\"$old_hashValue\"/hashValue=\"$hashValue\"/g; s/size=\"$old_size\"/size=\"$size\"/g" "$manifest_file"
rm "$manifest_file.bak"
echo "Manifest updated with new hashValue and size for $mar_file"
done
}
sign_mars() {
if [ ! -f "$SIGNMAR" ]; then
echo "Error: signmar not found at $SIGNMAR. Build the engine first." >&2
exit 1
@@ -127,14 +166,37 @@ sign_mar() {
create_nss_config_dir
echo ""
echo "Signing $mar_file..."
# mar [-C workingDir] -d NSSConfigDir -n certname -s archive.mar out_signed_archive.mar
"$SIGNMAR" -d "$NSS_CONFIG_DIR" -n "mar_cert" -s "$mar_file" "$mar_file".signed
echo "Signed $mar_file. Verifying signature..."
"$SIGNMAR" -d "$NSS_CONFIG_DIR" -n "mar_cert" -v "$mar_file".signed
mv "$mar_file".signed "$mar_file"
echo "Successfully signed $mar_file"
folders=(
linux.mar
linux-aarch64.mar
windows.mar
windows-arm64.mar
macos.mar
)
# each folder will contain the .mar files for that platform, and the signature will be written in-place
for folder in "${folders[@]}"; do
if [ -d "$folder" ]; then
for mar_file in "$folder"/*.mar; do
if [ -f "$mar_file" ]; then
echo ""
echo "Signing $mar_file..."
# mar [-C workingDir] -d NSSConfigDir -n certname -s archive.mar out_signed_archive.mar
"$SIGNMAR" -d "$NSS_CONFIG_DIR" -n "mar_sig" -s "$mar_file" "$mar_file".signed
echo "Signed $mar_file. Verifying signature..."
"$SIGNMAR" -d "$NSS_CONFIG_DIR" -n "mar_sig" -v "$mar_file".signed
mv "$mar_file".signed "$mar_file"
echo "Successfully signed $mar_file"
update_manifests "$mar_file"
else
echo "No .mar files found in $folder, skipping."
exit 1
fi
done
else
echo "Directory $folder not found, skipping."
exit 1
fi
done
cleanup_certs
}
@@ -147,13 +209,13 @@ case "$1" in
import_cert
;;
-s)
sign_mar "$2"
sign_mars
;;
*)
echo "Usage: $0 [-g] [-i] [-s <mar_file>]" >&2
echo " -g Generate MAR signing certificates" >&2
echo " -i Import the certificate into the updater (release_primary.der)" >&2
echo " -s <mar_file> Sign the given .mar file in-place" >&2
echo "Usage: $0 [-g] [-i] [-s]" >&2
echo " -g Generate MAR signing certificates" >&2
echo " -i Import the certificate into the updater (release_primary.der)" >&2
echo " -s Sign *.mar files in the current directory in-place" >&2
exit 1
;;
esac

View File

@@ -504,6 +504,7 @@ groupbox h2 {
#setting-control-sidebarChatbotFieldset,
#aiControlsDescription,
#category-ai-features,
#setting-control-supportFirefox,
.mission-message,
html|setting-group[data-subcategory="layout"] {
display: none !important;