Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,25 @@ jobs:
MARKETING_VERSION_INPUT: ${{ inputs.marketing_version }}
run: bash scripts/ci/resolve_version.sh

- name: Validate release options
env:
SIGN_INPUT: ${{ inputs.sign }}
NOTARIZE_INPUT: ${{ inputs.notarize }}
run: bash scripts/ci/validate_release_options.sh

- name: Validate immutable release state
env:
GH_TOKEN: ${{ github.token }}
run: bash scripts/ci/check_release_publish_state.sh

- name: Ensure notarization secrets
if: ${{ inputs.notarize == true }}
env:
APPLE_NOTARIZATION_KEY_ID: ${{ secrets.APPLE_NOTARIZATION_KEY_ID }}
APPLE_NOTARIZATION_ISSUER_ID: ${{ secrets.APPLE_NOTARIZATION_ISSUER_ID }}
APPLE_NOTARIZATION_PRIVATE_KEY: ${{ secrets.APPLE_NOTARIZATION_PRIVATE_KEY }}
run: bash scripts/ci/ensure_notarization_secrets.sh

build:
name: Build (${{ matrix.arch }})
runs-on: macos-26
Expand Down
1 change: 1 addition & 0 deletions scripts/ci/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__pycache__/
50 changes: 32 additions & 18 deletions scripts/ci/archive.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,37 @@ ARCHIVE_PATH="$RUNNER_TEMP/${APP_NAME}-${ARCH_LABEL}.xcarchive"
MACOS_SIGNING_IDENTITY="${MACOS_SIGNING_IDENTITY:-}"
MACOS_TEAM_ID="${MACOS_TEAM_ID:-}"

xcodebuild archive \
-project "$PROJECT" \
-scheme "$SCHEME" \
-configuration Release \
-destination "generic/platform=macOS" \
-archivePath "$ARCHIVE_PATH" \
-derivedDataPath "$RUNNER_TEMP/DerivedData-${ARCH_LABEL}" \
ARCHS="$ARCHS" \
ONLY_ACTIVE_ARCH=NO \
SKIP_INSTALL=NO \
BUILD_LIBRARY_FOR_DISTRIBUTION=YES \
CURRENT_PROJECT_VERSION="$BUILD_NUMBER" \
MARKETING_VERSION="$MARKETING_VERSION" \
CODE_SIGN_STYLE=Manual \
CODE_SIGN_IDENTITY="$MACOS_SIGNING_IDENTITY" \
DEVELOPMENT_TEAM="$MACOS_TEAM_ID" \
ENABLE_HARDENED_RUNTIME=YES \
OTHER_CODE_SIGN_FLAGS="--timestamp"
XCODEBUILD_ARGS=(
archive
-project "$PROJECT"
-scheme "$SCHEME"
-configuration Release
-destination "generic/platform=macOS"
-archivePath "$ARCHIVE_PATH"
-derivedDataPath "$RUNNER_TEMP/DerivedData-${ARCH_LABEL}"
ARCHS="$ARCHS"
ONLY_ACTIVE_ARCH=NO
SKIP_INSTALL=NO
BUILD_LIBRARY_FOR_DISTRIBUTION=YES
CURRENT_PROJECT_VERSION="$BUILD_NUMBER"
MARKETING_VERSION="$MARKETING_VERSION"
)

if [[ -n "$MACOS_SIGNING_IDENTITY" && -n "$MACOS_TEAM_ID" ]]; then
XCODEBUILD_ARGS+=(
CODE_SIGN_STYLE=Manual
CODE_SIGN_IDENTITY="$MACOS_SIGNING_IDENTITY"
DEVELOPMENT_TEAM="$MACOS_TEAM_ID"
ENABLE_HARDENED_RUNTIME=YES
OTHER_CODE_SIGN_FLAGS="--timestamp"
)
else
XCODEBUILD_ARGS+=(
CODE_SIGNING_ALLOWED=NO
CODE_SIGNING_REQUIRED=NO
)
fi

xcodebuild "${XCODEBUILD_ARGS[@]}"

ci_write_github_env "ARCHIVE_PATH" "${ARCHIVE_PATH}"
1 change: 1 addition & 0 deletions scripts/ci/create_dmg.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ STAGING_DIR="$RUNNER_TEMP/staging-${ARCH_LABEL}"
ci_require_dir "$APP_PATH" "App not found"

mkdir -p "$DIST_DIR"
rm -rf "$STAGING_DIR"
mkdir -p "$STAGING_DIR"

ditto "$APP_PATH" "$STAGING_DIR/$APP_NAME.app"
Expand Down
15 changes: 9 additions & 6 deletions scripts/ci/create_github_release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@
set -euo pipefail
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/lib.sh"

RELEASE_FILES=(
dist/*.dmg
dist/*.dmg.sha256
dist/checksums.txt
)

ci_require_env "RELEASE_TAG"
ci_require_env "GITHUB_REPOSITORY"

shopt -s nullglob
RELEASE_FILES=(dist/*.dmg dist/*.dmg.sha256 dist/checksums.txt)
shopt -u nullglob

if [[ "${#RELEASE_FILES[@]}" -eq 0 ]]; then
echo "No release artifacts found in dist/" >&2
exit 1
fi

for release_file in "${RELEASE_FILES[@]}"; do
ci_require_file "${release_file}" "Release artifact not found"
done
Expand Down
16 changes: 16 additions & 0 deletions scripts/ci/ensure_notarization_secrets.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -euo pipefail
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/lib.sh"

missing=()
[[ -z "${APPLE_NOTARIZATION_KEY_ID:-}" ]] && missing+=("APPLE_NOTARIZATION_KEY_ID")
[[ -z "${APPLE_NOTARIZATION_ISSUER_ID:-}" ]] && missing+=("APPLE_NOTARIZATION_ISSUER_ID")
[[ -z "${APPLE_NOTARIZATION_PRIVATE_KEY:-}" ]] && missing+=("APPLE_NOTARIZATION_PRIVATE_KEY")

if (( ${#missing[@]} > 0 )); then
echo "Missing required notarization secrets:" >&2
for item in "${missing[@]}"; do
echo " ${item}" >&2
done
exit 1
fi
53 changes: 48 additions & 5 deletions scripts/ci/notarize_dmg.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,56 @@ if (( ${#missing[@]} > 0 )); then
fi

KEY_PATH="$RUNNER_TEMP/notarytool-key.p8"
SUBMISSION_ID_PATH="$RUNNER_TEMP/notary-submission-id.txt"
SUBMISSION_JSON_PATH="$RUNNER_TEMP/notary-submission.json"
python3 scripts/ci/write_notary_key.py "$KEY_PATH"
chmod 600 "$KEY_PATH"

xcrun notarytool submit "$DMG_PATH" \
--key "$KEY_PATH" \
--key-id "$APPLE_NOTARIZATION_KEY_ID" \
--issuer "$APPLE_NOTARIZATION_ISSUER_ID" \
--wait
hdiutil verify "$DMG_PATH"

cleanup() {
rm -f "$KEY_PATH" "$SUBMISSION_ID_PATH" "$SUBMISSION_JSON_PATH"
}

print_notary_log() {
if [[ -f "$SUBMISSION_ID_PATH" ]]; then
submission_id="$(cat "$SUBMISSION_ID_PATH")"
if [[ -n "$submission_id" ]]; then
echo "Fetching notarization log for submission ${submission_id}..." >&2
xcrun notarytool log "$submission_id" \
--key "$KEY_PATH" \
--key-id "$APPLE_NOTARIZATION_KEY_ID" \
--issuer "$APPLE_NOTARIZATION_ISSUER_ID" || true
fi
fi
}

trap cleanup EXIT

if ! xcrun notarytool submit "$DMG_PATH" \
--key "$KEY_PATH" \
--key-id "$APPLE_NOTARIZATION_KEY_ID" \
--issuer "$APPLE_NOTARIZATION_ISSUER_ID" \
--wait \
--output-format json >"$SUBMISSION_JSON_PATH"; then
if [[ -s "$SUBMISSION_JSON_PATH" ]]; then
python3 - "$SUBMISSION_JSON_PATH" "$SUBMISSION_ID_PATH" <<'PY'
import json
import pathlib
import sys

payload = json.loads(pathlib.Path(sys.argv[1]).read_text())
submission_id = payload.get("id")
if submission_id:
pathlib.Path(sys.argv[2]).write_text(submission_id)
PY
fi
print_notary_log
exit 1
fi

submission_id="$(python3 -c 'import json, pathlib, sys; print(json.loads(pathlib.Path(sys.argv[1]).read_text())["id"])' "$SUBMISSION_JSON_PATH")"
printf '%s' "$submission_id" > "$SUBMISSION_ID_PATH"

xcrun stapler staple "$DMG_PATH"
xcrun stapler validate "$DMG_PATH"
11 changes: 11 additions & 0 deletions scripts/ci/validate_release_options.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -euo pipefail
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/lib.sh"

SIGN_INPUT="${SIGN_INPUT:-true}"
NOTARIZE_INPUT="${NOTARIZE_INPUT:-false}"

if [[ "${NOTARIZE_INPUT}" == "true" && "${SIGN_INPUT}" != "true" ]]; then
echo "Notarization requires signing. Set sign=true when notarize=true." >&2
exit 1
fi