Skip to content

Build and publish preview version #111

Build and publish preview version

Build and publish preview version #111

name: Build and publish preview version
on:
workflow_dispatch:
# Cancel previous runs for the same branch when a new one is triggered
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# Least-privilege root (CIS GHA 1.2). Tag-pushing / deploy jobs grant
# `contents: write` per-job below: `publish-sc-preview` (welder deploy),
# `publish-git-tag` (git push tag), and `finalize` (notify/comment).
permissions:
contents: read
jobs:
prepare:
name: Prepare preview build
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
steps:
# Trust-root ref guard. Preview signing uses cosign keyless identity
# `branch-preview.yaml@refs/heads/<branch>` and the documented
# preview verification regex pins `@refs/heads/.+`. workflow_dispatch
# ALSO allows dispatching from a tag (`refs/tags/<tag>`), which
# would sign artifacts under an identity that no documented
# verifier accepts — fail fast in that case.
- name: Refuse to run on non-branch ref
if: "!startsWith(github.ref, 'refs/heads/')"
run: |
echo "::error title=branch-preview.yaml requires a branch ref::Got github.ref=$GITHUB_REF; this workflow signs preview artifacts under the preview trust root (refs/heads/* only). Re-dispatch from a branch."
exit 1
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
- name: Get next version
uses: reecetech/version-increment@a29aa752dc3b8118a2dc2ed93faf0e95a73a9c7e # 2024.10.1
id: base-version
with:
scheme: "calver"
increment: "patch"
use_api: "false"
- name: Build preview version string
id: version
run: |
SHORT_SHA=$(git rev-parse --short=7 HEAD)
VERSION="${{ steps.base-version.outputs.version }}-preview.${SHORT_SHA}"
echo "version=${VERSION}" >> $GITHUB_OUTPUT
build-setup:
name: Build Setup (clean, tools, schemas, lint, fmt)
runs-on: blacksmith-8vcpu-ubuntu-2204
needs: prepare
outputs:
cicd-bot-telegram-token: ${{ steps.telegram-secrets.outputs.cicd-bot-telegram-token }}
cicd-bot-telegram-chat-id: ${{ steps.telegram-secrets.outputs.cicd-bot-telegram-chat-id }}
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
- uses: fregante/setup-git-user@024bc0b8e177d7e77203b48dab6fb45666854b35 # v2.0.2
- name: Set up Go with Blacksmith caching
uses: useblacksmith/setup-go@647ac649bd5b480f2a262e3e3e5f4d150ed452ad # v6.0.1
with:
go-version: '1.25'
- name: install sc + welder tools
uses: simple-container-com/actions/setup-sc-tooling@0af5a697f24ea484991660619d0ae42d50343b9d # main
- name: prepare secrets for build
run: |
cat << EOF > ./.sc/cfg.default.yaml
${{ secrets.SC_CONFIG }}
EOF
cat << EOF > ./.sc/cfg.test.yaml
${{ secrets.SC_CONFIG }}
EOF
sc secrets reveal
- name: get openai key
id: get-openai-key
run: |
echo "openai-key=$(sc stack secret-get -s dist openai-api-key 2>/dev/null || echo '')" >> $GITHUB_OUTPUT
- name: prepare sc tool (rebuild)
shell: bash
env:
OPENAI_API_KEY: ${{ steps.get-openai-key.outputs.openai-key }}
SKIP_EMBEDDINGS: "true"
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |-
gh auth setup-git
welder run rebuild
- name: clean
run: |
mkdir -p dist
rm -fR dist/*
mkdir -p .sc/stacks/dist/bundle
rm -fR .sc/stacks/dist/bundle/*
mkdir -p docs/site
rm -fR docs/site/*
mkdir -p docs/schemas
rm -fR docs/schemas/*
- name: tools
run: |
cat tools.go | grep _ | awk -F'"' '{print $2}' | xargs -tI % go get %
go mod download
go generate -tags tools
go mod tidy
- name: generate-schemas
run: |
echo "Generating JSON Schema files for Simple Container resources..."
go build -o bin/schema-gen ./cmd/schema-gen
bin/schema-gen docs/schemas
echo "Successfully generated JSON Schema files in docs/schemas/"
- name: fmt
run: |
go mod tidy
bin/gofumpt -l -w ./
bin/golangci-lint run --fix --timeout 3m -v
- name: get telegram secrets
id: telegram-secrets
run: |
echo "cicd-bot-telegram-token=$(./bin/sc stack secret-get -s dist cicd-bot-telegram-token)" >> $GITHUB_OUTPUT
echo "cicd-bot-telegram-chat-id=$(./bin/sc stack secret-get -s dist cicd-bot-telegram-chat-id)" >> $GITHUB_OUTPUT
- name: upload bin directory artifacts
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: bin-tools
path: bin
retention-days: 1
build-platforms:
name: Build sc for ${{ matrix.os }}/${{ matrix.arch }}
runs-on: blacksmith-8vcpu-ubuntu-2204
needs: [prepare, build-setup]
permissions:
contents: read
id-token: write # OIDC for keyless cosign + attest-build-provenance
attestations: write
strategy:
matrix:
include:
- os: linux
arch: amd64
- os: darwin
arch: arm64
- os: darwin
arch: amd64
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
- name: Set up Go with Blacksmith caching
uses: useblacksmith/setup-go@647ac649bd5b480f2a262e3e3e5f4d150ed452ad # v6.0.1
with:
go-version: '1.25'
- name: create build directories
run: |
mkdir -p dist
mkdir -p .sc/stacks/dist/bundle
- name: build sc for ${{ matrix.os }}/${{ matrix.arch }}
env:
GOOS: ${{ matrix.os }}
GOARCH: ${{ matrix.arch }}
CGO_ENABLED: "0"
VERSION: ${{ needs.prepare.outputs.version }}
run: |
echo "Building for ${GOOS}/${GOARCH}..."
if [ "${GOOS}" = "windows" ]; then export EXT=".exe"; else export EXT=""; fi
go build -ldflags "-s -w -X=github.com/simple-container-com/api/internal/build.Version=${VERSION}" -o dist/${GOOS}-${GOARCH}/sc${EXT} ./cmd/sc
tar -czf .sc/stacks/dist/bundle/sc-${GOOS}-${GOARCH}.tar.gz -C dist/${GOOS}-${GOARCH} sc${EXT}
cp .sc/stacks/dist/bundle/sc-${GOOS}-${GOARCH}.tar.gz .sc/stacks/dist/bundle/sc-${GOOS}-${GOARCH}-v${VERSION}.tar.gz
# Phase 2 attestation (mirrors push.yaml). Soft-fail per step — the
# tarball itself is the publish artifact. Preview builds only publish
# versioned tarballs (no unversioned twin), so sidecars are per-version.
- name: SHA-256 sidecar for ${{ matrix.os }}/${{ matrix.arch }}
env:
GOOS: ${{ matrix.os }}
GOARCH: ${{ matrix.arch }}
VERSION: ${{ needs.prepare.outputs.version }}
run: |
set -euo pipefail
cd .sc/stacks/dist/bundle
sha256sum "sc-${GOOS}-${GOARCH}-v${VERSION}.tar.gz" > "sc-${GOOS}-${GOARCH}-v${VERSION}.tar.gz.sha256"
- name: Install attestation tools
id: install_attest_tools
continue-on-error: true
uses: simple-container-com/actions/install-attest-tools@0af5a697f24ea484991660619d0ae42d50343b9d # main
- name: Generate CycloneDX SBOM for sc-${{ matrix.os }}-${{ matrix.arch }}
id: sbom_tarball
continue-on-error: true
env:
GOOS: ${{ matrix.os }}
GOARCH: ${{ matrix.arch }}
VERSION: ${{ needs.prepare.outputs.version }}
run: |
set -euo pipefail
cd .sc/stacks/dist/bundle
syft scan "dir:../../../../dist/${GOOS}-${GOARCH}" \
-o "cyclonedx-json=sc-${GOOS}-${GOARCH}-v${VERSION}.tar.gz.sbom.cdx.json"
- name: Cosign sign-blob (keyless, bundle) for sc-${{ matrix.os }}-${{ matrix.arch }}
id: cosign_sign_tarball
continue-on-error: true
env:
COSIGN_EXPERIMENTAL: "1"
GOOS: ${{ matrix.os }}
GOARCH: ${{ matrix.arch }}
VERSION: ${{ needs.prepare.outputs.version }}
run: |
set -euo pipefail
cd .sc/stacks/dist/bundle
tarball="sc-${GOOS}-${GOARCH}-v${VERSION}.tar.gz"
cosign sign-blob --yes --bundle "${tarball}.cosign-bundle" "${tarball}"
- name: SLSA build provenance for sc-${{ matrix.os }}-${{ matrix.arch }}
id: slsa_tarball
continue-on-error: true
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
with:
subject-path: .sc/stacks/dist/bundle/sc-${{ matrix.os }}-${{ matrix.arch }}-v${{ needs.prepare.outputs.version }}.tar.gz
- name: Materialize SLSA provenance bundle next to tarball
if: steps.slsa_tarball.outcome == 'success'
continue-on-error: true
env:
BUNDLE_PATH: ${{ steps.slsa_tarball.outputs.bundle-path }}
GOOS: ${{ matrix.os }}
GOARCH: ${{ matrix.arch }}
VERSION: ${{ needs.prepare.outputs.version }}
run: |
cp "$BUNDLE_PATH" ".sc/stacks/dist/bundle/sc-${GOOS}-${GOARCH}-v${VERSION}.tar.gz.sigstore.json"
- name: upload build artifacts
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: sc-${{ matrix.os }}-${{ matrix.arch }}
path: |
.sc/stacks/dist/bundle/sc-${{ matrix.os }}-${{ matrix.arch }}-v*.tar.gz
.sc/stacks/dist/bundle/sc-${{ matrix.os }}-${{ matrix.arch }}-v*.tar.gz.sha256
.sc/stacks/dist/bundle/sc-${{ matrix.os }}-${{ matrix.arch }}-v*.tar.gz.cosign-bundle
.sc/stacks/dist/bundle/sc-${{ matrix.os }}-${{ matrix.arch }}-v*.tar.gz.sigstore.json
.sc/stacks/dist/bundle/sc-${{ matrix.os }}-${{ matrix.arch }}-v*.tar.gz.sbom.cdx.json
retention-days: 1
build-binaries:
name: Build ${{ matrix.target }} binary
runs-on: blacksmith-8vcpu-ubuntu-2204
needs: [prepare, build-setup]
strategy:
matrix:
include:
- target: github-actions
cmd: github-actions
output: dist/github-actions
- target: cloud-helpers
cmd: cloud-helpers
output: dist/cloud-helpers
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
- name: Set up Go with Blacksmith caching
uses: useblacksmith/setup-go@647ac649bd5b480f2a262e3e3e5f4d150ed452ad # v6.0.1
with:
go-version: '1.25'
- name: create build directories
run: |
mkdir -p dist
- name: build ${{ matrix.target }}
env:
VERSION: ${{ needs.prepare.outputs.version }}
CGO_ENABLED: "0"
run: |
go build -a -installsuffix cgo -ldflags "-s -w -X=github.com/simple-container-com/api/internal/build.Version=${VERSION}" -o ${{ matrix.output }} ./cmd/${{ matrix.cmd }}
- name: upload ${{ matrix.target }} binary
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ${{ matrix.target }}-binary
path: ${{ matrix.output }}
retention-days: 1
test:
name: Run tests
runs-on: blacksmith-8vcpu-ubuntu-2204
needs: [prepare, build-setup]
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
- name: Set up Go with Blacksmith caching
uses: useblacksmith/setup-go@647ac649bd5b480f2a262e3e3e5f4d150ed452ad # v6.0.1
with:
go-version: '1.25'
- name: test
run: |
go test ./...
docker-build:
name: Docker build and push preview ${{ matrix.target }} image
runs-on: blacksmith-8vcpu-ubuntu-2204
needs: [prepare, build-setup, build-binaries, test]
permissions:
contents: read
id-token: write # OIDC token for keyless cosign + attest-build-provenance
attestations: write
strategy:
matrix:
include:
- target: github-actions
binary: github-actions
dockerfile: github-actions.Dockerfile
image_repo: simplecontainer/github-actions
tag_prefix: "simplecontainer/github-actions:"
- target: cloud-helpers
binary: cloud-helpers
dockerfile: cloud-helpers.aws.Dockerfile
image_repo: simplecontainer/cloud-helpers
tag_prefix: "simplecontainer/cloud-helpers:aws-"
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
- name: download ${{ matrix.target }} binary
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: ${{ matrix.target }}-binary
path: dist
- name: fix binary permissions
run: chmod +x dist/${{ matrix.binary }}
- name: install sc tool
uses: simple-container-com/actions/install-sc@0af5a697f24ea484991660619d0ae42d50343b9d # main
- name: prepare secrets for build
run: |
cat << EOF > ./.sc/cfg.default.yaml
${{ secrets.SC_CONFIG }}
EOF
sc secrets reveal
- name: Setup Docker Buildx with advanced caching
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
with:
driver-opts: |
image=moby/buildkit:buildx-stable-1
- name: Disable IPv6 (Blacksmith runners have broken IPv6 to Docker Hub)
run: sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1
- name: Docker login using SC secrets
run: |
sc stack secret-get -s dist dockerhub-cicd-token | docker login --username simplecontainer --password-stdin
- name: Build and push preview ${{ matrix.target }} image
id: build_and_push
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
context: .
file: ${{ matrix.dockerfile }}
platforms: linux/amd64
tags: ${{ matrix.tag_prefix }}${{ needs.prepare.outputs.version }}
push: true
cache-from: type=gha
cache-to: type=gha,mode=max
provenance: false
# Phase 2 attestation (mirrors push.yaml). Preview builds get the SAME
# security guarantees as production releases so consumers pin-testing a
# preview version (per project_sc_preview memory: PAY-SPACE pins workflows
# to versioned preview builds) can verify the same way they verify prod.
- name: Sign + attest ${{ matrix.target }} (SBOM + cosign + SLSA)
id: signattest
if: steps.build_and_push.outcome == 'success'
uses: simple-container-com/actions/sign-and-attest@0af5a697f24ea484991660619d0ae42d50343b9d # main
with:
image-ref: ${{ matrix.image_repo }}@${{ steps.build_and_push.outputs.digest }}
image-name: ${{ matrix.target }}
subject-name: index.docker.io/${{ matrix.image_repo }}
subject-digest: ${{ steps.build_and_push.outputs.digest }}
# Phase 2 bake-in soft-fail. Mirrors push.yaml.
soft-fail: 'true'
- name: Record image digest for verify-attestations
if: steps.build_and_push.outcome == 'success'
env:
DIGEST: ${{ steps.build_and_push.outputs.digest }}
IMAGE_REPO: ${{ matrix.image_repo }}
run: |
set -euo pipefail
mkdir -p digests
printf '%s@%s\n' "$IMAGE_REPO" "$DIGEST" > "digests/${{ matrix.target }}.txt"
- name: Upload digest artifact for ${{ matrix.target }}
if: steps.build_and_push.outcome == 'success'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: image-digest-${{ matrix.target }}
path: digests/${{ matrix.target }}.txt
retention-days: 1
- name: Soft-fail aggregator for ${{ matrix.target }} attestation
if: always() && steps.build_and_push.outcome == 'success'
env:
SIGN_OUTCOME: ${{ steps.signattest.outputs.sign-outcome }}
SBOM_OUTCOME: ${{ steps.signattest.outputs.sbom-outcome }}
ATTEST_SBOM_OUTCOME: ${{ steps.signattest.outputs.attest-outcome }}
SLSA_OUTCOME: ${{ steps.signattest.outputs.slsa-outcome }}
run: |
fail=0
for v in "$SIGN_OUTCOME" "$SBOM_OUTCOME" "$ATTEST_SBOM_OUTCOME" "$SLSA_OUTCOME"; do
if [ "$v" != "success" ]; then fail=1; fi
done
if [ "$fail" -eq 1 ]; then
echo "::warning title=Attestation incomplete::${{ matrix.target }} preview published but attestation steps failed (sign=$SIGN_OUTCOME sbom=$SBOM_OUTCOME attest-sbom=$ATTEST_SBOM_OUTCOME slsa=$SLSA_OUTCOME)."
else
echo "All attestation steps succeeded for ${{ matrix.target }} preview."
fi
publish-sc-preview:
name: Publish preview SC binaries to dist
runs-on: blacksmith-8vcpu-ubuntu-2204
# Does not need docker-build — SC binary publishing is independent of the Docker image.
# Runs in parallel with publish-git-tag.
needs: [prepare, build-setup, build-platforms, test]
permissions:
contents: write # welder deploy reads release artifacts + updates dist
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
- name: download all sc platform artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: artifacts
pattern: sc-*
- name: download bin tools artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: bin-tools
path: bin
- name: fix bin tools permissions
run: chmod +x bin/*
- name: install sc tool
uses: simple-container-com/actions/install-sc@0af5a697f24ea484991660619d0ae42d50343b9d # main
- name: prepare secrets for build
run: |
cat << EOF > ./.sc/cfg.default.yaml
${{ secrets.SC_CONFIG }}
EOF
cat << EOF > ./.sc/cfg.test.yaml
${{ secrets.SC_CONFIG }}
EOF
sc secrets reveal
- name: assemble preview dist bundle (versioned tarballs only)
env:
VERSION: ${{ needs.prepare.outputs.version }}
run: |
set -euo pipefail
mkdir -p .sc/stacks/dist/bundle
rm -fR .sc/stacks/dist/bundle/*
# Copy only versioned tarballs + their sidecars (.sha256,
# .cosign-bundle, .sigstore.json, .sbom.cdx.json) — do NOT add sc.sh
# or the version file. Preserves the unversioned-latest pointer for
# users running sc.sh without a version pin.
shopt -s nullglob
for f in artifacts/sc-*/*-v${VERSION}.tar.gz \
artifacts/sc-*/*-v${VERSION}.tar.gz.sha256 \
artifacts/sc-*/*-v${VERSION}.tar.gz.cosign-bundle \
artifacts/sc-*/*-v${VERSION}.tar.gz.sigstore.json \
artifacts/sc-*/*-v${VERSION}.tar.gz.sbom.cdx.json; do
cp "$f" .sc/stacks/dist/bundle/
done
echo "Bundle contents:"
ls -la .sc/stacks/dist/bundle/
- name: publish preview sc binaries
env:
VERSION: ${{ needs.prepare.outputs.version }}
run: |
# Deploy only the dist stack — welder deploy -e prod would also deploy
# the docs stack which requires docs/site/ that we don't build in preview.
./bin/sc deploy -s dist -e prod --skip-refresh
publish-git-tag:
name: Create release commit and push git tag
runs-on: blacksmith-8vcpu-ubuntu-2204
# Only needs docker-build — the tag must point to a commit referencing a published Docker image.
# Does not need build-platforms or publish-sc-preview. Runs in parallel with publish-sc-preview.
needs: [prepare, docker-build]
permissions:
contents: write # commits the release branch + pushes the preview tag
# GH_TOKEN must be visible to every step that runs git (checkout, commit,
# push) because `gh auth setup-git` installs `gh auth git-credential` as
# the credential helper — and that helper reads $GH_TOKEN from the
# invoking step's env when git pushes. Setting it once at job level
# avoids the "fatal: could not read Username" failure from per-step env.
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
fetch-depth: 0
- uses: fregante/setup-git-user@024bc0b8e177d7e77203b48dab6fb45666854b35 # v2.0.2
- name: configure git credential helper
run: gh auth setup-git
- name: create release branch and update action.yml image tags
env:
VERSION: ${{ needs.prepare.outputs.version }}
run: |
RELEASE_BRANCH="release/${VERSION}"
git checkout -b "${RELEASE_BRANCH}"
# Rewrite whatever tag the action.yml files currently pin (latest,
# staging, …) to the preview version. Matching a fixed base tag is
# brittle: #284 switched :staging -> :latest and silently broke every
# preview build, because this sed still looked for :staging — the
# rewrite became a no-op, leaving "nothing to commit" downstream.
find .github/actions -name "action.yml" | while read f; do
sed -i -E "s|(docker://simplecontainer/github-actions):[A-Za-z0-9._-]+|\1:${VERSION}|g" "$f"
done
echo "Updated action.yml files:"
grep -r "docker://simplecontainer/github-actions:" .github/actions/
# Fail loudly if the rewrite matched nothing (base-tag drift again),
# instead of producing a confusing empty-commit error in the next step.
if ! grep -rq "docker://simplecontainer/github-actions:${VERSION}" .github/actions/; then
echo "::error::No action.yml image tag was rewritten to ${VERSION} — the base image tag pattern drifted. Update the sed above."
exit 1
fi
- name: commit, tag and push
env:
VERSION: ${{ needs.prepare.outputs.version }}
run: |
RELEASE_BRANCH="release/${VERSION}"
git add .github/actions/*/action.yml
git commit -m "chore: release preview v${VERSION} - update github-actions image tag"
git tag "v${VERSION}"
git push origin "${RELEASE_BRANCH}"
git push origin "v${VERSION}"
finalize:
name: Finalize preview build
runs-on: ubuntu-latest
if: ${{ always() }}
permissions:
contents: write
needs:
- prepare
- build-setup
- publish-sc-preview
- publish-git-tag
- docker-build
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
if: ${{ always() }}
with:
persist-credentials: false
- name: Extract git reference
id: extract_git_ref
if: ${{ always() }}
shell: bash
env:
COMMIT_MESSAGE: ${{ github.event.head_commit.message || github.event.workflow_run.head_commit.message }}
run: |-
message="$(printf '%s' "$COMMIT_MESSAGE" | tr -d '\n')"
if [ ${#message} -gt 200 ]; then
truncated_message="${message:0:80}...${message: -80}"
message="$truncated_message"
fi
echo "branch=$GITHUB_REF_NAME" >> $GITHUB_OUTPUT
echo "message=$message" >> $GITHUB_OUTPUT
echo "author=$GITHUB_ACTOR" >> $GITHUB_OUTPUT
echo "url=$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" >> $GITHUB_OUTPUT
- name: Write build summary
if: ${{ !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }}
env:
VERSION: ${{ needs.prepare.outputs.version }}
BRANCH: ${{ github.ref_name }}
# GHA evaluates ${{ '${{' }} to the literal string ${{ so SC_CONFIG_EXPR becomes
# the printable text "${{ secrets.SC_CONFIG }}" for use in markdown examples.
SC_CONFIG_EXPR: "${{ '${{' }} secrets.SC_CONFIG }}"
run: |
cat >> "$GITHUB_STEP_SUMMARY" << ENDSUMMARY
## Preview build \`v${VERSION}\`
### Use SC GitHub Actions at this version
Reference any SC action with the \`@v${VERSION}\` tag:
\`\`\`yaml
- uses: simple-container-com/api/.github/actions/deploy-client-stack@v${VERSION}
with:
stack-name: my-stack
sc-config: ${SC_CONFIG_EXPR}
- uses: simple-container-com/api/.github/actions/provision-parent-stack@v${VERSION}
with:
stack-name: my-stack
sc-config: ${SC_CONFIG_EXPR}
- uses: simple-container-com/api/.github/actions/destroy@v${VERSION}
with:
stack-name: my-stack
sc-config: ${SC_CONFIG_EXPR}
\`\`\`
Docker image: \`simplecontainer/github-actions:${VERSION}\`
### Install this SC version in your CI
\`\`\`yaml
- uses: simple-container-com/actions/install-sc@0af5a697f24ea484991660619d0ae42d50343b9d # main
with:
version: ${VERSION}
\`\`\`
> Preview build from branch \`${BRANCH}\`. The \`install-sc\` action pins the binary to the exact preview version above and verifies it on download.
ENDSUMMARY
- name: Notify Telegram (success)
if: ${{ success() && !contains(needs.*.result, 'failure') }}
continue-on-error: true
uses: simple-container-com/actions/notify-telegram@0af5a697f24ea484991660619d0ae42d50343b9d # main
with:
chat-id: ${{ needs.build-setup.outputs.cicd-bot-telegram-chat-id }}
token: ${{ needs.build-setup.outputs.cicd-bot-telegram-token }}
text: '✅ Preview published: '
link-url: ${{ format('{0}/{1}/actions/runs/{2}', github.server_url, github.repository, github.run_id) }}
link-text: 'v${{ needs.prepare.outputs.version }}'
suffix: ' on ${{ github.head_ref || github.ref_name }} by ${{ steps.extract_git_ref.outputs.author }}'
- name: Notify Telegram (failure)
if: ${{ failure() || contains(needs.*.result, 'failure') }}
continue-on-error: true
uses: simple-container-com/actions/notify-telegram@0af5a697f24ea484991660619d0ae42d50343b9d # main
with:
chat-id: ${{ needs.build-setup.outputs.cicd-bot-telegram-chat-id }}
token: ${{ needs.build-setup.outputs.cicd-bot-telegram-token }}
text: '❗ Preview failed: '
link-url: ${{ format('{0}/{1}/actions/runs/{2}', github.server_url, github.repository, github.run_id) }}
link-text: 'v${{ needs.prepare.outputs.version }}'
suffix: ' on ${{ github.head_ref || github.ref_name }} by ${{ steps.extract_git_ref.outputs.author }}'
- name: Build failed due to previously failed steps
id: fail_if_needed
if: ${{ failure() || contains(needs.*.result, 'failure') }}
shell: bash
run: |-
exit 1