dsh 0.2.0-rc.2: in-container update (experimental channel), path-agnostic compose, upstream patches adapted to 0.1.x/0.2.x
This commit is contained in:
commit
e6dcef9bf5
302 files changed
+75178
No files matched your search
+289
@@ -0,0 +1,289 @@
|
||||
name: Publish Supported Platform Target
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- container/environment/definition.json
|
||||
- release/supported-target.json
|
||||
- release/official-dsh-policy.json
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: production-supported-target
|
||||
cancel-in-progress: false
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
name: Sign and publish Supported Target
|
||||
if: github.ref == 'refs/heads/main'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
environment: production-release
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout protected branch
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
cache: npm
|
||||
cache-dependency-path: |
|
||||
container/control-plane/services/management/package-lock.json
|
||||
container/environment/resources/plugins/platform-management/package/package-lock.json
|
||||
|
||||
- name: Install Management runtime dependencies
|
||||
run: |
|
||||
npm ci --omit=dev --ignore-scripts --no-audit --no-fund --prefix container/control-plane/services/management
|
||||
npm ci --omit=dev --ignore-scripts --no-audit --no-fund --legacy-peer-deps --prefix container/environment/resources/plugins/platform-management/package
|
||||
|
||||
- name: Verify merged Supported Target
|
||||
id: target
|
||||
run: |
|
||||
result="$(node container/platform/tools/supported-target.mjs validate \
|
||||
release/supported-target.json container/environment/definition.json)"
|
||||
dsh_version="$(jq -er '.target.latestSupportedDsh' <<<"$result")"
|
||||
environment_version="$(jq -er '.target.environment' <<<"$result")"
|
||||
[[ "$environment_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]
|
||||
printf 'dsh_version=%s\n' "$dsh_version" >> "$GITHUB_OUTPUT"
|
||||
printf 'environment_version=%s\n' "$environment_version" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Run release contract tests
|
||||
run: |
|
||||
npm test --prefix container/platform
|
||||
npm test --prefix container/control-plane/services/gateway
|
||||
node container/test/compose-config.mjs
|
||||
|
||||
- name: Install protected public trust bundle
|
||||
env:
|
||||
RECOVERY_ROOT_PUBLIC_KEY: ${{ secrets.DSH_RECOVERY_ROOT_PUBLIC_KEY }}
|
||||
KEYRING_JSON_BASE64: ${{ secrets.DSH_KEYRING_JSON_BASE64 }}
|
||||
KEYRING_SIGNATURE_BASE64: ${{ secrets.DSH_KEYRING_SIGNATURE_BASE64 }}
|
||||
run: |
|
||||
test -n "$RECOVERY_ROOT_PUBLIC_KEY"
|
||||
test -n "$KEYRING_JSON_BASE64"
|
||||
test -n "$KEYRING_SIGNATURE_BASE64"
|
||||
mkdir -p "$RUNNER_TEMP/production-trust"
|
||||
printf '%s\n' "$RECOVERY_ROOT_PUBLIC_KEY" > "$RUNNER_TEMP/production-trust/recovery-root.spki.base64"
|
||||
printf '%s' "$KEYRING_JSON_BASE64" | base64 --decode > "$RUNNER_TEMP/production-trust/keyring.json"
|
||||
printf '%s' "$KEYRING_SIGNATURE_BASE64" | base64 --decode > "$RUNNER_TEMP/production-trust/keyring.sig.json"
|
||||
|
||||
- name: Resolve signed channel and target sequence
|
||||
id: sequence
|
||||
run: |
|
||||
channel="$RUNNER_TEMP/release-channel"
|
||||
keyring_sha256="$(sha256sum "$RUNNER_TEMP/production-trust/keyring.json" | cut -d ' ' -f 1)"
|
||||
previous=-
|
||||
reuse=false
|
||||
if git ls-remote --exit-code origin refs/heads/release-channel >/dev/null 2>&1; then
|
||||
git fetch origin refs/heads/release-channel
|
||||
channel_commit="$(git rev-parse FETCH_HEAD)"
|
||||
git worktree add --detach "$channel" "$channel_commit"
|
||||
current_sequence="$(jq -er .targetSequence "$channel/stable.json")"
|
||||
previous="$channel/targets/$current_sequence"
|
||||
test -d "$previous"
|
||||
for name in \
|
||||
stable.json \
|
||||
stable.sig.json \
|
||||
keyring.json \
|
||||
keyring.sig.json \
|
||||
bootstrap.manifest.json \
|
||||
bootstrap.manifest.sig.json; do
|
||||
test -f "$previous/$name"
|
||||
done
|
||||
for name in stable.json stable.sig.json keyring.json keyring.sig.json; do
|
||||
cmp "$channel/$name" "$previous/$name"
|
||||
done
|
||||
if test -f "$channel/channel.json" \
|
||||
&& test "$(jq -er .sourceCommit "$channel/channel.json")" = "$GITHUB_SHA" \
|
||||
&& test "$(jq -er .keyringSha256 "$channel/channel.json")" = "$keyring_sha256"; then
|
||||
sequence="$current_sequence"
|
||||
reuse=true
|
||||
else
|
||||
test "$current_sequence" -lt 9007199254740991
|
||||
sequence="$((current_sequence + 1))"
|
||||
fi
|
||||
else
|
||||
git worktree add --detach "$channel" "$GITHUB_SHA"
|
||||
git -C "$channel" checkout --orphan release-channel
|
||||
git -C "$channel" rm -rf .
|
||||
sequence=1
|
||||
channel_commit=
|
||||
fi
|
||||
{
|
||||
printf 'channel=%s\n' "$channel"
|
||||
printf 'channel_commit=%s\n' "$channel_commit"
|
||||
printf 'keyring_sha256=%s\n' "$keyring_sha256"
|
||||
printf 'previous=%s\n' "$previous"
|
||||
printf 'reuse=%s\n' "$reuse"
|
||||
printf 'sequence=%s\n' "$sequence"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
printf 'Target sequence: %s (reuse: %s)\n' "$sequence" "$reuse" >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
- name: Download reviewed DSH npm Artifact
|
||||
if: steps.sequence.outputs.reuse != 'true'
|
||||
env:
|
||||
DSH_VERSION: ${{ steps.target.outputs.dsh_version }}
|
||||
run: |
|
||||
mkdir -p "$RUNNER_TEMP/platform-release-input"
|
||||
npm pack "@deepseek-ai/dsh@${DSH_VERSION}" --pack-destination "$RUNNER_TEMP/platform-release-input" >/dev/null
|
||||
tarball="$(find "$RUNNER_TEMP/platform-release-input" -maxdepth 1 -type f -name '*.tgz' -print -quit)"
|
||||
test -n "$tarball"
|
||||
printf 'DSH_TARBALL=%s\n' "$tarball" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Prepare signed immutable target
|
||||
if: steps.sequence.outputs.reuse != 'true'
|
||||
env:
|
||||
RELEASE_PRIVATE_KEY: ${{ secrets.DSH_RELEASE_PRIVATE_KEY }}
|
||||
TARGET_SEQUENCE: ${{ steps.sequence.outputs.sequence }}
|
||||
PREVIOUS_STABLE: ${{ steps.sequence.outputs.previous }}
|
||||
run: |
|
||||
test -n "$RELEASE_PRIVATE_KEY"
|
||||
umask 077
|
||||
private_key="$RUNNER_TEMP/current-release-private.pem"
|
||||
trap 'rm -f "$private_key"' EXIT
|
||||
printf '%s\n' "$RELEASE_PRIVATE_KEY" > "$private_key"
|
||||
artifact_base_url="https://raw.githubusercontent.com/${GITHUB_REPOSITORY}/release-channel/targets/${TARGET_SEQUENCE}/"
|
||||
SOURCE_DATE_EPOCH="$(git show -s --format=%ct "$GITHUB_SHA")"
|
||||
export SOURCE_DATE_EPOCH
|
||||
node container/platform/tools/prepare-release.mjs \
|
||||
release/supported-target.json container/environment/definition.json release/official-dsh-policy.json \
|
||||
"$RUNNER_TEMP/production-trust" "$private_key" "$DSH_TARBALL" "$PREVIOUS_STABLE" \
|
||||
"$TARGET_SEQUENCE" "$artifact_base_url" "$RUNNER_TEMP/platform-release"
|
||||
rm -f "$private_key"
|
||||
trap - EXIT
|
||||
|
||||
- name: Reuse an already published target after retry
|
||||
if: steps.sequence.outputs.reuse == 'true'
|
||||
env:
|
||||
TARGET_SEQUENCE: ${{ steps.sequence.outputs.sequence }}
|
||||
CHANNEL: ${{ steps.sequence.outputs.channel }}
|
||||
DSH_VERSION: ${{ steps.target.outputs.dsh_version }}
|
||||
ENVIRONMENT_VERSION: ${{ steps.target.outputs.environment_version }}
|
||||
run: |
|
||||
cp -a "$CHANNEL/targets/$TARGET_SEQUENCE" "$RUNNER_TEMP/platform-release"
|
||||
test "$(jq -er .desired.dsh.version "$RUNNER_TEMP/platform-release/stable.json")" = "$DSH_VERSION"
|
||||
test "$(jq -er .desired.environment.version "$RUNNER_TEMP/platform-release/stable.json")" = "$ENVIRONMENT_VERSION"
|
||||
|
||||
- name: Derive Environment release identity
|
||||
run: |
|
||||
node container/platform/tools/environment-release.mjs \
|
||||
"$RUNNER_TEMP/platform-release/bootstrap.manifest.json" \
|
||||
"$RUNNER_TEMP/platform-release/environment.manifest.json" \
|
||||
release/official-dsh-policy.json \
|
||||
"$RUNNER_TEMP/environment-release.json"
|
||||
|
||||
- name: Validate Environment version ownership
|
||||
id: environment-check
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
ENVIRONMENT_VERSION: ${{ steps.target.outputs.environment_version }}
|
||||
run: |
|
||||
tag="v${ENVIRONMENT_VERSION}"
|
||||
publish=true
|
||||
if gh release view "$tag" --json isDraft > "$RUNNER_TEMP/environment-release-state.json" 2>/dev/null; then
|
||||
if test "$(jq -er .isDraft "$RUNNER_TEMP/environment-release-state.json")" = false; then
|
||||
mkdir -p "$RUNNER_TEMP/published-environment"
|
||||
gh release download "$tag" --pattern environment-release.json --dir "$RUNNER_TEMP/published-environment"
|
||||
cmp "$RUNNER_TEMP/environment-release.json" "$RUNNER_TEMP/published-environment/environment-release.json"
|
||||
publish=false
|
||||
else
|
||||
mkdir -p "$RUNNER_TEMP/draft-environment"
|
||||
if gh release download "$tag" --pattern environment-release.json --dir "$RUNNER_TEMP/draft-environment" 2>/dev/null; then
|
||||
cmp "$RUNNER_TEMP/environment-release.json" "$RUNNER_TEMP/draft-environment/environment-release.json"
|
||||
fi
|
||||
fi
|
||||
elif git ls-remote --exit-code origin "refs/tags/$tag" >/dev/null 2>&1; then
|
||||
echo "Git tag $tag exists without a matching Environment Release" >&2
|
||||
exit 1
|
||||
fi
|
||||
printf 'publish=%s\n' "$publish" >> "$GITHUB_OUTPUT"
|
||||
printf 'tag=%s\n' "$tag" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Publish signed channel target
|
||||
env:
|
||||
CHANNEL: ${{ steps.sequence.outputs.channel }}
|
||||
EXISTING_CHANNEL_COMMIT: ${{ steps.sequence.outputs.channel_commit }}
|
||||
KEYRING_SHA256: ${{ steps.sequence.outputs.keyring_sha256 }}
|
||||
REUSE: ${{ steps.sequence.outputs.reuse }}
|
||||
TARGET_SEQUENCE: ${{ steps.sequence.outputs.sequence }}
|
||||
DSH_VERSION: ${{ steps.target.outputs.dsh_version }}
|
||||
ENVIRONMENT_VERSION: ${{ steps.target.outputs.environment_version }}
|
||||
run: |
|
||||
if test "$REUSE" = true; then
|
||||
commit="$EXISTING_CHANNEL_COMMIT"
|
||||
else
|
||||
target="$CHANNEL/targets/$TARGET_SEQUENCE"
|
||||
test ! -e "$target"
|
||||
mkdir -p "$target"
|
||||
cp -a "$RUNNER_TEMP/platform-release/." "$target/"
|
||||
for name in stable.json stable.sig.json keyring.json keyring.sig.json; do cp "$target/$name" "$CHANNEL/$name"; done
|
||||
# shellcheck disable=SC2016
|
||||
jq -n --arg sourceCommit "$GITHUB_SHA" --arg keyringSha256 "$KEYRING_SHA256" \
|
||||
--arg dshVersion "$DSH_VERSION" --arg environmentVersion "$ENVIRONMENT_VERSION" \
|
||||
--argjson targetSequence "$TARGET_SEQUENCE" \
|
||||
'{schema:1,sourceCommit:$sourceCommit,keyringSha256:$keyringSha256,targetSequence:$targetSequence,dshVersion:$dshVersion,environmentVersion:$environmentVersion}' \
|
||||
> "$CHANNEL/channel.json"
|
||||
git -C "$CHANNEL" config user.name github-actions
|
||||
git -C "$CHANNEL" config user.email github-actions@github.com
|
||||
git -C "$CHANNEL" add channel.json keyring.json keyring.sig.json stable.json stable.sig.json "targets/$TARGET_SEQUENCE"
|
||||
git -C "$CHANNEL" commit -m "release: publish target sequence $TARGET_SEQUENCE"
|
||||
commit="$(git -C "$CHANNEL" rev-parse HEAD)"
|
||||
git -C "$CHANNEL" push origin HEAD:refs/heads/release-channel
|
||||
fi
|
||||
# shellcheck disable=SC2016
|
||||
printf 'Published signed channel sequence `%s` at `%s`.\n' "$TARGET_SEQUENCE" "$commit" >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
- name: Publish Environment Release
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
PUBLISH_ENVIRONMENT: ${{ steps.environment-check.outputs.publish }}
|
||||
ENVIRONMENT_TAG: ${{ steps.environment-check.outputs.tag }}
|
||||
ENVIRONMENT_VERSION: ${{ steps.target.outputs.environment_version }}
|
||||
DSH_VERSION: ${{ steps.target.outputs.dsh_version }}
|
||||
TARGET_SEQUENCE: ${{ steps.sequence.outputs.sequence }}
|
||||
run: |
|
||||
prune_environment_assets() {
|
||||
gh release view "$ENVIRONMENT_TAG" --json assets --jq '.assets[].name' | while IFS= read -r name; do
|
||||
if test "$name" != environment-release.json; then
|
||||
gh release delete-asset "$ENVIRONMENT_TAG" "$name" --yes
|
||||
fi
|
||||
done
|
||||
}
|
||||
if test "$PUBLISH_ENVIRONMENT" != true; then
|
||||
prune_environment_assets
|
||||
test "$(gh release view "$ENVIRONMENT_TAG" --json assets --jq '.assets[].name')" = environment-release.json
|
||||
exit 0
|
||||
fi
|
||||
assets="$RUNNER_TEMP/environment-release-assets"
|
||||
mkdir -p "$assets"
|
||||
cp "$RUNNER_TEMP/environment-release.json" "$assets/"
|
||||
notes="$RUNNER_TEMP/environment-release-notes.md"
|
||||
# shellcheck disable=SC2016
|
||||
{
|
||||
printf 'Container Environment: `%s`\n\n' "$ENVIRONMENT_VERSION"
|
||||
printf 'Supported DSH at publication: `%s`\n\n' "$DSH_VERSION"
|
||||
printf 'Initial signed target sequence: `%s`\n' "$TARGET_SEQUENCE"
|
||||
} > "$notes"
|
||||
if ! gh release view "$ENVIRONMENT_TAG" >/dev/null 2>&1; then
|
||||
gh release create "$ENVIRONMENT_TAG" --draft --target "$GITHUB_SHA" \
|
||||
--title "$ENVIRONMENT_TAG" --notes-file "$notes"
|
||||
fi
|
||||
gh release edit "$ENVIRONMENT_TAG" --draft --target "$GITHUB_SHA" \
|
||||
--title "$ENVIRONMENT_TAG" --notes-file "$notes"
|
||||
gh release upload "$ENVIRONMENT_TAG" "$assets"/* --clobber
|
||||
prune_environment_assets
|
||||
find "$assets" -maxdepth 1 -type f -printf '%f\n' | sort > "$RUNNER_TEMP/local-environment-assets"
|
||||
gh release view "$ENVIRONMENT_TAG" --json assets --jq '.assets[].name' | sort > "$RUNNER_TEMP/remote-environment-assets"
|
||||
diff -u "$RUNNER_TEMP/local-environment-assets" "$RUNNER_TEMP/remote-environment-assets"
|
||||
gh release edit "$ENVIRONMENT_TAG" --draft=false --latest \
|
||||
--title "$ENVIRONMENT_TAG" --notes-file "$notes"
|
||||
Reference in new issue
Block a user