源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
Dependency audit / audit (push) Canceled after 0s
CI / plan (push) Canceled after 0s
Gitoxide helper admission / macos-latest (push) Canceled after 0s
Gitoxide helper admission / ubuntu-latest (push) Canceled after 0s
Gitoxide helper admission / windows-latest (push) Canceled after 0s
Runtime Host peer admission / quality (push) Canceled after 0s
Windows recovery / windows_recovery (push) Canceled after 0s
CI / heavy (push) Canceled after 0s
CI / test (push) Canceled after 0s
Dependency audit / audit (push) Canceled after 0s
CI / plan (push) Canceled after 0s
Gitoxide helper admission / macos-latest (push) Canceled after 0s
Gitoxide helper admission / ubuntu-latest (push) Canceled after 0s
Gitoxide helper admission / windows-latest (push) Canceled after 0s
Runtime Host peer admission / quality (push) Canceled after 0s
Windows recovery / windows_recovery (push) Canceled after 0s
CI / heavy (push) Canceled after 0s
CI / test (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,538 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
name: Release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
source_reference_tag:
|
||||
description: Exact approved ASF source candidate tag (v<version>-incubating-rc<positive-integer>)
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: product-release
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
release-identity:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
outputs:
|
||||
version: ${{ steps.identity.outputs.version }}
|
||||
tag: ${{ steps.identity.outputs.tag }}
|
||||
source_commit: ${{ steps.identity.outputs.source_commit }}
|
||||
source_reference_tag: ${{ steps.identity.outputs.source_reference_tag }}
|
||||
dmg: ${{ steps.identity.outputs.dmg }}
|
||||
exe: ${{ steps.identity.outputs.exe }}
|
||||
cli_archive: ${{ steps.identity.outputs.cli_archive }}
|
||||
node_version: ${{ steps.identity.outputs.node_version }}
|
||||
npm_version: ${{ steps.identity.outputs.npm_version }}
|
||||
node_archive: ${{ steps.identity.outputs.node_archive }}
|
||||
node_archive_sha256: ${{ steps.identity.outputs.node_archive_sha256 }}
|
||||
node_source_url: ${{ steps.identity.outputs.node_source_url }}
|
||||
|
||||
steps:
|
||||
- name: Check out the dispatched commit
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
ref: ${{ github.sha }}
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Resolve product release identity
|
||||
id: identity
|
||||
env:
|
||||
GITHUB_SHA: ${{ github.sha }}
|
||||
SOURCE_REFERENCE_TAG: ${{ inputs.source_reference_tag }}
|
||||
run: node scripts/product-release-identity.mjs
|
||||
|
||||
- name: Require the exact ASF source reference
|
||||
env:
|
||||
RELEASE_REF: ${{ github.ref }}
|
||||
RELEASE_REPOSITORY: ${{ github.repository }}
|
||||
SOURCE_COMMIT: ${{ steps.identity.outputs.source_commit }}
|
||||
SOURCE_REFERENCE_TAG: ${{ steps.identity.outputs.source_reference_tag }}
|
||||
run: |
|
||||
if [[ "$RELEASE_REPOSITORY" != "apache/maka" ]]; then
|
||||
echo "Product releases must run in apache/maka; found $RELEASE_REPOSITORY" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ "$RELEASE_REF" != "refs/tags/$SOURCE_REFERENCE_TAG" ]]; then
|
||||
echo "Product releases must be dispatched from $SOURCE_REFERENCE_TAG; found $RELEASE_REF" >&2
|
||||
exit 1
|
||||
fi
|
||||
git fetch --force --no-tags origin \
|
||||
"refs/tags/$SOURCE_REFERENCE_TAG:refs/tags/$SOURCE_REFERENCE_TAG"
|
||||
test "$(git cat-file -t "refs/tags/$SOURCE_REFERENCE_TAG")" = tag
|
||||
test "$(git rev-parse "refs/tags/$SOURCE_REFERENCE_TAG^{commit}")" = "$SOURCE_COMMIT"
|
||||
git fetch --no-tags origin main:refs/remotes/origin/main
|
||||
git merge-base --is-ancestor "$SOURCE_COMMIT" origin/main
|
||||
|
||||
desktop:
|
||||
needs: release-identity
|
||||
strategy:
|
||||
# Both platforms ship from one dispatch, so a failure on one still leaves
|
||||
# the other artifact available for diagnosis.
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- platform: macos
|
||||
runner: macos-15
|
||||
- platform: windows
|
||||
runner: windows-2025
|
||||
runs-on: ${{ matrix.runner }}
|
||||
environment: release
|
||||
timeout-minutes: 75
|
||||
defaults:
|
||||
run:
|
||||
# Windows runners default to pwsh; the release steps are written once,
|
||||
# in bash, for both platforms.
|
||||
shell: bash
|
||||
|
||||
steps:
|
||||
- name: Check out the dispatched commit
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
ref: ${{ needs.release-identity.outputs.source_commit }}
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up the pinned release Node.js
|
||||
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version: ${{ needs.release-identity.outputs.node_version }}
|
||||
cache: npm
|
||||
|
||||
- name: Select and verify the pinned npm release toolchain
|
||||
run: |
|
||||
npm install --global --no-audit --no-fund "npm@${{ needs.release-identity.outputs.npm_version }}"
|
||||
test "$(npm --version)" = "${{ needs.release-identity.outputs.npm_version }}"
|
||||
|
||||
- name: Install dependencies with the pinned npm
|
||||
run: npm ci
|
||||
|
||||
- name: Audit production dependencies
|
||||
run: npm audit --omit=dev --audit-level=moderate
|
||||
|
||||
- name: Audit shipped desktop closure
|
||||
run: node scripts/audit-shipped-dependencies.mjs
|
||||
|
||||
- name: Update stable Rust for Desktop native artifacts
|
||||
run: rustup update stable --no-self-update
|
||||
|
||||
- name: Write App Store Connect API key
|
||||
if: matrix.platform == 'macos'
|
||||
env:
|
||||
APPLE_API_KEY_CONTENT: ${{ secrets.APPLE_API_KEY }}
|
||||
APPLE_API_KEY_PATH: ${{ runner.temp }}/AuthKey_Maka.p8
|
||||
run: |
|
||||
umask 077
|
||||
printf '%s' "$APPLE_API_KEY_CONTENT" > "$APPLE_API_KEY_PATH"
|
||||
|
||||
- name: Package notarized app and signed DMG
|
||||
if: matrix.platform == 'macos'
|
||||
env:
|
||||
CSC_LINK: ${{ secrets.CSC_LINK }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
|
||||
APPLE_API_KEY: ${{ runner.temp }}/AuthKey_Maka.p8
|
||||
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
|
||||
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
|
||||
run: npm run package:macos-arm64
|
||||
|
||||
- name: Notarize and staple the signed final DMG
|
||||
if: matrix.platform == 'macos'
|
||||
env:
|
||||
APPLE_API_KEY: ${{ runner.temp }}/AuthKey_Maka.p8
|
||||
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
|
||||
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
|
||||
DMG_PATH: apps/desktop/release/${{ needs.release-identity.outputs.dmg }}
|
||||
run: |
|
||||
codesign --verify --verbose=4 "$DMG_PATH"
|
||||
xcrun notarytool submit "$DMG_PATH" \
|
||||
--key "$APPLE_API_KEY" \
|
||||
--key-id "$APPLE_API_KEY_ID" \
|
||||
--issuer "$APPLE_API_ISSUER" \
|
||||
--wait
|
||||
xcrun stapler staple "$DMG_PATH"
|
||||
|
||||
codesign --verify --verbose=4 "$DMG_PATH"
|
||||
xcrun stapler validate "$DMG_PATH"
|
||||
spctl --assess \
|
||||
--type open \
|
||||
--context context:primary-signature \
|
||||
--verbose=4 \
|
||||
"$DMG_PATH"
|
||||
|
||||
- name: Verify the final DMG
|
||||
if: matrix.platform == 'macos'
|
||||
run: npm run verify:macos-arm64 -- "apps/desktop/release/${{ needs.release-identity.outputs.dmg }}"
|
||||
|
||||
- name: Build the version-bumped macOS update
|
||||
if: matrix.platform == 'macos'
|
||||
env:
|
||||
CSC_LINK: ${{ secrets.CSC_LINK }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
|
||||
run: npm run package:macos-autoupdate-next
|
||||
|
||||
- name: Verify macOS automatic update end to end
|
||||
if: matrix.platform == 'macos'
|
||||
run: |
|
||||
npm run verify:macos-autoupdate -- \
|
||||
"apps/desktop/release/Maka-${{ needs.release-identity.outputs.version }}-mac-arm64.zip" \
|
||||
apps/desktop/release-autoupdate-next
|
||||
|
||||
# Windows has no Authenticode certificate yet, so this build is unsigned
|
||||
# and there is nothing to notarize between packaging and verification.
|
||||
- name: Package the Windows installer and ZIP
|
||||
if: matrix.platform == 'windows'
|
||||
run: npm run package:windows-x64
|
||||
|
||||
- name: Verify the Windows release
|
||||
if: matrix.platform == 'windows'
|
||||
run: npm run verify:windows-x64 -- "apps/desktop/release/${{ needs.release-identity.outputs.exe }}"
|
||||
|
||||
- name: Download and verify the pinned Windows upgrade baseline
|
||||
id: previous
|
||||
if: matrix.platform == 'windows'
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
previous_exe="$(node scripts/prepare-windows-upgrade-baseline.mjs \
|
||||
"${{ needs.release-identity.outputs.version }}" artifacts/windows-upgrade-baseline)"
|
||||
echo "exe=$previous_exe" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Exercise pinned Windows upgrade and uninstall
|
||||
if: matrix.platform == 'windows'
|
||||
run: |
|
||||
npm run verify:windows-installer -- \
|
||||
"apps/desktop/release/${{ needs.release-identity.outputs.exe }}" \
|
||||
"${{ steps.previous.outputs.exe }}"
|
||||
|
||||
- name: Build the version-bumped autoupdate installer
|
||||
if: matrix.platform == 'windows'
|
||||
run: npm run package:windows-autoupdate-next
|
||||
|
||||
- name: Verify automatic update end to end
|
||||
if: matrix.platform == 'windows'
|
||||
run: |
|
||||
npm run verify:windows-autoupdate -- \
|
||||
"apps/desktop/release/${{ needs.release-identity.outputs.exe }}" \
|
||||
apps/desktop/release-autoupdate-next
|
||||
|
||||
- name: Prove deterministic mid-install failure rollback
|
||||
if: matrix.platform == 'windows'
|
||||
run: |
|
||||
npm run verify:windows-installer-rollback -- \
|
||||
"apps/desktop/release/${{ needs.release-identity.outputs.exe }}" \
|
||||
apps/desktop/release-autoupdate-next
|
||||
|
||||
- name: Stage the exact product artifact group
|
||||
run: >-
|
||||
node scripts/product-release-artifacts.mjs stage
|
||||
"desktop-${{ matrix.platform }}"
|
||||
apps/desktop/release
|
||||
"${{ runner.temp }}/release-assets"
|
||||
|
||||
- name: Upload the verified release assets
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: release-desktop-${{ matrix.platform }}-${{ github.run_attempt }}
|
||||
path: ${{ runner.temp }}/release-assets
|
||||
if-no-files-found: error
|
||||
retention-days: 30
|
||||
|
||||
- name: Remove temporary release credentials
|
||||
if: always() && matrix.platform == 'macos'
|
||||
run: rm -f "${{ runner.temp }}/AuthKey_Maka.p8"
|
||||
|
||||
cli-macos-arm64:
|
||||
needs: release-identity
|
||||
runs-on: macos-15
|
||||
environment: release
|
||||
timeout-minutes: 45
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
steps:
|
||||
- name: Check out the dispatched commit
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
ref: ${{ needs.release-identity.outputs.source_commit }}
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up the pinned release Node.js
|
||||
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version: ${{ needs.release-identity.outputs.node_version }}
|
||||
cache: npm
|
||||
|
||||
- name: Select and verify the pinned npm release toolchain
|
||||
run: |
|
||||
npm install --global --no-audit --no-fund "npm@${{ needs.release-identity.outputs.npm_version }}"
|
||||
test "$(npm --version)" = "${{ needs.release-identity.outputs.npm_version }}"
|
||||
|
||||
- name: Install dependencies with the pinned npm
|
||||
run: npm ci
|
||||
|
||||
- name: Audit production dependencies
|
||||
run: npm audit --omit=dev --audit-level=moderate
|
||||
|
||||
- name: Build the CLI production workspace closure
|
||||
run: |
|
||||
npm --workspace maka-agent run build:workspace-deps
|
||||
npm --workspace maka-agent run build
|
||||
npm run check:cli-third-party-notices
|
||||
|
||||
- name: Download and verify the official Node runtime
|
||||
env:
|
||||
NODE_ARCHIVE: ${{ runner.temp }}/${{ needs.release-identity.outputs.node_archive }}
|
||||
NODE_ARCHIVE_SHA256: ${{ needs.release-identity.outputs.node_archive_sha256 }}
|
||||
NODE_SOURCE_URL: ${{ needs.release-identity.outputs.node_source_url }}
|
||||
run: |
|
||||
curl --proto '=https' --tlsv1.2 --fail --location \
|
||||
--output "$NODE_ARCHIVE" "$NODE_SOURCE_URL"
|
||||
actual="$(shasum -a 256 "$NODE_ARCHIVE" | awk '{print $1}')"
|
||||
test "$actual" = "$NODE_ARCHIVE_SHA256"
|
||||
|
||||
- name: Write App Store Connect API key
|
||||
env:
|
||||
APPLE_API_KEY_CONTENT: ${{ secrets.APPLE_API_KEY }}
|
||||
APPLE_API_KEY_PATH: ${{ runner.temp }}/AuthKey_Maka.p8
|
||||
run: |
|
||||
umask 077
|
||||
printf '%s' "$APPLE_API_KEY_CONTENT" > "$APPLE_API_KEY_PATH"
|
||||
|
||||
- name: Package signed and notarized CLI and TUI
|
||||
env:
|
||||
CSC_LINK: ${{ secrets.CSC_LINK }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
|
||||
APPLE_API_KEY: ${{ runner.temp }}/AuthKey_Maka.p8
|
||||
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
|
||||
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
|
||||
MAKA_CLI_NODE_ARCHIVE: ${{ runner.temp }}/${{ needs.release-identity.outputs.node_archive }}
|
||||
MAKA_CLI_RELEASE_SIGNING: '1'
|
||||
run: npm run package:cli:macos-arm64
|
||||
|
||||
- name: Verify the final CLI and TUI artifact
|
||||
env:
|
||||
MAKA_CLI_REQUIRE_RELEASE_SIGNING: '1'
|
||||
run: >-
|
||||
npm run verify:cli:macos-arm64 --
|
||||
"apps/desktop/release/${{ needs.release-identity.outputs.cli_archive }}"
|
||||
|
||||
- name: Stage the exact product artifact group
|
||||
run: >-
|
||||
node scripts/product-release-artifacts.mjs stage
|
||||
"cli-macos-arm64"
|
||||
apps/desktop/release
|
||||
"${{ runner.temp }}/release-assets"
|
||||
|
||||
- name: Upload the verified CLI release assets
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: release-cli-macos-arm64-${{ github.run_attempt }}
|
||||
path: ${{ runner.temp }}/release-assets
|
||||
if-no-files-found: error
|
||||
retention-days: 30
|
||||
|
||||
- name: Remove temporary release credentials
|
||||
if: always()
|
||||
run: rm -f "${{ runner.temp }}/AuthKey_Maka.p8"
|
||||
|
||||
publish:
|
||||
# One draft release carries both platforms, so it is created once, after
|
||||
# every platform has been packaged and verified.
|
||||
needs: [release-identity, desktop, cli-macos-arm64]
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
permissions:
|
||||
contents: write
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
steps:
|
||||
- name: Check out the dispatched commit
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
ref: ${{ needs.release-identity.outputs.source_commit }}
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Download the verified release assets
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
pattern: release-*-${{ github.run_attempt }}
|
||||
path: release-assets
|
||||
merge-multiple: true
|
||||
|
||||
- name: Set up the pinned release Node.js
|
||||
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version: ${{ needs.release-identity.outputs.node_version }}
|
||||
package-manager-cache: false
|
||||
|
||||
- name: Select the pinned npm release toolchain
|
||||
run: |
|
||||
npm install --global --no-audit --no-fund "npm@${{ needs.release-identity.outputs.npm_version }}"
|
||||
test "$(npm --version)" = "${{ needs.release-identity.outputs.npm_version }}"
|
||||
|
||||
- name: Install the release verifier dependencies
|
||||
run: npm ci --ignore-scripts --no-audit --no-fund
|
||||
|
||||
- name: Verify the exact product artifact manifest
|
||||
run: node scripts/product-release-artifacts.mjs verify release-assets
|
||||
|
||||
- name: Record the immutable publication evidence
|
||||
env:
|
||||
GITHUB_SHA: ${{ needs.release-identity.outputs.source_commit }}
|
||||
SOURCE_REFERENCE_TAG: ${{ needs.release-identity.outputs.source_reference_tag }}
|
||||
run: |
|
||||
node scripts/product-release-artifacts.mjs record \
|
||||
release-assets \
|
||||
"$RUNNER_TEMP/product-release.json" \
|
||||
"$GITHUB_REPOSITORY" \
|
||||
"$GITHUB_RUN_ID" \
|
||||
"$GITHUB_RUN_ATTEMPT"
|
||||
|
||||
- name: Upload the immutable publication evidence
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: product-release-record-${{ github.run_attempt }}
|
||||
path: ${{ runner.temp }}/product-release.json
|
||||
if-no-files-found: error
|
||||
compression-level: 0
|
||||
retention-days: 30
|
||||
|
||||
- name: Revalidate the live ASF source reference
|
||||
env:
|
||||
SOURCE_COMMIT: ${{ needs.release-identity.outputs.source_commit }}
|
||||
SOURCE_REFERENCE_TAG: ${{ needs.release-identity.outputs.source_reference_tag }}
|
||||
run: |
|
||||
git fetch --force --no-tags origin \
|
||||
"refs/tags/$SOURCE_REFERENCE_TAG:refs/tags/$SOURCE_REFERENCE_TAG"
|
||||
test "$(git cat-file -t "refs/tags/$SOURCE_REFERENCE_TAG")" = tag
|
||||
test "$(git rev-parse "refs/tags/$SOURCE_REFERENCE_TAG^{commit}")" = "$SOURCE_COMMIT"
|
||||
git fetch --no-tags origin main:refs/remotes/origin/main
|
||||
git merge-base --is-ancestor "$SOURCE_COMMIT" origin/main
|
||||
|
||||
- name: Ensure the exact product tag
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
TAG: ${{ needs.release-identity.outputs.tag }}
|
||||
SOURCE_COMMIT: ${{ needs.release-identity.outputs.source_commit }}
|
||||
run: |
|
||||
gh auth setup-git
|
||||
node scripts/product-release-tag.mjs ensure "$TAG" "$SOURCE_COMMIT"
|
||||
|
||||
- name: Create or update the draft GitHub Release
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
VERSION: ${{ needs.release-identity.outputs.version }}
|
||||
TAG: ${{ needs.release-identity.outputs.tag }}
|
||||
SOURCE_COMMIT: ${{ needs.release-identity.outputs.source_commit }}
|
||||
SOURCE_REFERENCE_TAG: ${{ needs.release-identity.outputs.source_reference_tag }}
|
||||
run: |
|
||||
notes="Maka Desktop and the required Apple Silicon CLI/TUI artifact built from approved ASF source reference ${SOURCE_REFERENCE_TAG} at commit ${SOURCE_COMMIT}.
|
||||
|
||||
Before publishing, download these draft assets on another Apple Silicon Mac and on a Windows x64 machine, and complete .github/RELEASE_CHECKLIST.md.
|
||||
|
||||
The Windows build is unsigned: SmartScreen warns on first launch, and the download has to be checked against its .sha256 file.
|
||||
|
||||
These files are convenience binaries built from the approved ASF source release; they are not ASF release artifacts.
|
||||
|
||||
Known limitations: Computer Use and Gitoxide-backed workspace execution are not included in this release. The Desktop convenience artifacts do not distribute a Git runtime."
|
||||
|
||||
if gh release view "$TAG" >/dev/null 2>&1; then
|
||||
is_draft="$(gh release view "$TAG" --json isDraft --jq .isDraft)"
|
||||
if [[ "$is_draft" != "true" ]]; then
|
||||
echo "Release ${TAG} is already published and cannot be replaced." >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
gh release create "$TAG" \
|
||||
--draft \
|
||||
--verify-tag \
|
||||
--prerelease=false \
|
||||
--latest=false \
|
||||
--title "Maka ${VERSION}" \
|
||||
--notes "$notes"
|
||||
fi
|
||||
|
||||
if [[ "$(gh release view "$TAG" --json isDraft --jq .isDraft)" != "true" ]]; then
|
||||
echo "Release ${TAG} was published while recovery was running." >&2
|
||||
exit 1
|
||||
fi
|
||||
gh release edit "$TAG" \
|
||||
--prerelease=false \
|
||||
--latest=false \
|
||||
--title "Maka ${VERSION}" \
|
||||
--notes "$notes"
|
||||
actual_prerelease="$(gh release view "$TAG" --json isPrerelease --jq .isPrerelease)"
|
||||
if [[ "$actual_prerelease" != "false" ]]; then
|
||||
echo "Release ${TAG} must not be a prerelease." >&2
|
||||
exit 1
|
||||
fi
|
||||
asset_names="$(gh release view "$TAG" --json assets --jq '.assets[].name')"
|
||||
declare -A expected_assets=()
|
||||
declare -A existing_assets=()
|
||||
mapfile -t local_assets < <(find release-assets -maxdepth 1 -type f -printf '%f\n' | sort)
|
||||
for asset in "${local_assets[@]}"; do
|
||||
expected_assets["$asset"]=1
|
||||
done
|
||||
existing_dir="$RUNNER_TEMP/existing-release-assets"
|
||||
mkdir -p "$existing_dir"
|
||||
if [[ -n "$asset_names" ]]; then
|
||||
while IFS= read -r asset; do
|
||||
if [[ -z "${expected_assets[$asset]+present}" ]]; then
|
||||
echo "Draft ${TAG} contains unexpected asset ${asset}; inspect and remove it manually before retrying." >&2
|
||||
exit 1
|
||||
fi
|
||||
gh release download "$TAG" --pattern "$asset" --dir "$existing_dir"
|
||||
if ! cmp -s "release-assets/$asset" "$existing_dir/$asset"; then
|
||||
echo "Draft ${TAG} asset ${asset} differs from the verified artifact." >&2
|
||||
exit 1
|
||||
fi
|
||||
existing_assets["$asset"]=1
|
||||
done <<< "$asset_names"
|
||||
fi
|
||||
missing_assets=()
|
||||
for asset in "${local_assets[@]}"; do
|
||||
if [[ -z "${existing_assets[$asset]+present}" ]]; then
|
||||
missing_assets+=("release-assets/$asset")
|
||||
fi
|
||||
done
|
||||
release_state="$(gh release view "$TAG" --json isDraft,isPrerelease --jq '[.isDraft, .isPrerelease] | map(tostring) | join(" ")')"
|
||||
if [[ "$release_state" != "true false" ]]; then
|
||||
echo "Release ${TAG} changed state while assets were checked: ${release_state}." >&2
|
||||
exit 1
|
||||
fi
|
||||
if (( ${#missing_assets[@]} > 0 )); then
|
||||
gh release upload "$TAG" "${missing_assets[@]}"
|
||||
fi
|
||||
|
||||
{
|
||||
echo "Draft release ${TAG} created from ${SOURCE_COMMIT}."
|
||||
echo "Release workflow run: ${GITHUB_RUN_ID}, attempt: ${GITHUB_RUN_ATTEMPT}."
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
Reference in New Issue
Block a user