Skip to content

Commit b84c716

Browse files
committed
Expand release workflow manifest gen
1 parent 4fd1f5f commit b84c716

File tree

5 files changed

+305
-21
lines changed

5 files changed

+305
-21
lines changed

.github/workflows/release.yml

Lines changed: 236 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
fail-fast: false
2121
matrix:
2222
service:
23-
- { name: gateway, context: api_gateway, dockerfile: api_gateway/Dockerfile }
23+
- { name: bridge, context: api_gateway, dockerfile: api_gateway/Dockerfile }
2424
- { name: quartermaster, context: api_tenants, dockerfile: api_tenants/Dockerfile }
2525
- { name: commodore, context: api_control, dockerfile: api_control/Dockerfile }
2626
- { name: purser, context: api_billing, dockerfile: api_billing/Dockerfile }
@@ -73,6 +73,7 @@ jobs:
7373
with:
7474
context: .
7575
file: ${{ matrix.service.dockerfile }}
76+
platforms: linux/amd64,linux/arm64
7677
push: true
7778
provenance: true
7879
sbom: true
@@ -94,7 +95,7 @@ jobs:
9495
cat > dist/image-${{ matrix.service.name }}.json <<JSON
9596
{
9697
"name": "${{ matrix.service.name }}",
97-
"image": "${{ env.REGISTRY }}/frameworks-${{ matrix.service.name }}:${{ github.ref_name }}",
98+
"image": "docker.io/livepeerframeworks/frameworks-${{ matrix.service.name }}:${{ github.ref_name }}",
9899
"digest": "${{ steps.build.outputs.digest }}",
99100
"service_version": "${{ steps.svcver.outputs.version }}",
100101
"git_commit": "${{ github.sha }}"
@@ -197,6 +198,7 @@ jobs:
197198
password: ${{ secrets.DOCKERHUB_TOKEN }}
198199

199200
- name: Build and push Docker image
201+
id: build
200202
uses: docker/build-push-action@v5
201203
with:
202204
context: .
@@ -211,6 +213,24 @@ jobs:
211213
cache-from: type=gha,scope=${{ matrix.webapp.name }}
212214
cache-to: type=gha,mode=max,scope=${{ matrix.webapp.name }}
213215

216+
- name: Write digest artifact
217+
run: |
218+
mkdir -p dist
219+
cat > dist/image-${{ matrix.webapp.name }}.json <<JSON
220+
{
221+
"name": "${{ matrix.webapp.name }}",
222+
"image": "docker.io/livepeerframeworks/frameworks-${{ matrix.webapp.name }}:${{ github.ref_name }}",
223+
"digest": "${{ steps.build.outputs.digest }}",
224+
"git_commit": "${{ github.sha }}"
225+
}
226+
JSON
227+
228+
- name: Upload digest artifact
229+
uses: actions/upload-artifact@v4
230+
with:
231+
name: image-digest-${{ matrix.webapp.name }}
232+
path: dist/image-${{ matrix.webapp.name }}.json
233+
214234
- name: Upload static bundle artifact
215235
uses: actions/upload-artifact@v4
216236
with:
@@ -265,9 +285,83 @@ jobs:
265285
name: cli-${{ matrix.goos }}-${{ matrix.goarch }}
266286
path: dist/cli/*
267287

288+
build-service-binaries:
289+
name: Build Service Binaries
290+
runs-on: ubuntu-latest
291+
strategy:
292+
fail-fast: false
293+
matrix:
294+
service:
295+
- { name: bridge, context: api_gateway, cmd_path: ./cmd/bridge }
296+
- { name: quartermaster, context: api_tenants, cmd_path: ./cmd/quartermaster }
297+
- { name: commodore, context: api_control, cmd_path: ./cmd/commodore }
298+
- { name: purser, context: api_billing, cmd_path: ./cmd/purser }
299+
- { name: foghorn, context: api_balancing, cmd_path: ./cmd/foghorn }
300+
- { name: decklog, context: api_firehose, cmd_path: cmd/decklog/main.go }
301+
- { name: periscope-ingest, context: api_analytics_ingest, cmd_path: ./cmd/periscope }
302+
- { name: periscope-query, context: api_analytics_query, cmd_path: ./cmd/periscope }
303+
- { name: signalman, context: api_realtime, cmd_path: ./cmd/signalman }
304+
- { name: helmsman, context: api_sidecar, cmd_path: ./cmd/helmsman }
305+
arch:
306+
- { goos: linux, goarch: amd64 }
307+
- { goos: linux, goarch: arm64 }
308+
steps:
309+
- name: Checkout
310+
uses: actions/checkout@v4
311+
312+
- name: Setup Go
313+
uses: actions/setup-go@v5
314+
with:
315+
go-version: '1.22'
316+
cache-dependency-path: ${{ matrix.service.context }}/go.sum
317+
318+
- name: Read service version
319+
id: svcver
320+
run: |
321+
VERSION_FILE="${{ matrix.service.context }}/VERSION"
322+
if [[ -f "$VERSION_FILE" ]]; then
323+
echo "version=$(tr -d '\n' < "$VERSION_FILE")" >> "$GITHUB_OUTPUT"
324+
else
325+
echo "version=0.0.0" >> "$GITHUB_OUTPUT"
326+
fi
327+
328+
- name: Build binary
329+
env:
330+
GOOS: ${{ matrix.arch.goos }}
331+
GOARCH: ${{ matrix.arch.goarch }}
332+
CGO_ENABLED: 0
333+
run: |
334+
set -euo pipefail
335+
cd ${{ matrix.service.context }}
336+
337+
BINARY_NAME="frameworks-${{ matrix.service.name }}-${{ matrix.arch.goos }}-${{ matrix.arch.goarch }}"
338+
OUTPUT="frameworks-${{ matrix.service.name }}-${{ github.ref_name }}-${{ matrix.arch.goos }}-${{ matrix.arch.goarch }}"
339+
340+
go build -ldflags "\
341+
-X frameworks/pkg/version.Version=${{ github.ref_name }} \
342+
-X frameworks/pkg/version.GitCommit=${{ github.sha }} \
343+
-X frameworks/pkg/version.BuildDate=$(date -u '+%Y-%m-%dT%H:%M:%SZ') \
344+
-X frameworks/pkg/version.ComponentName=${{ matrix.service.name }} \
345+
-X frameworks/pkg/version.ComponentVersion=${{ steps.svcver.outputs.version }} \
346+
-s -w" \
347+
-o "${BINARY_NAME}" \
348+
${{ matrix.service.cmd_path }}
349+
350+
# Create output directory
351+
mkdir -p ../dist/binaries/${{ matrix.service.name }}
352+
353+
# Package binary with platform version in filename
354+
tar czf "../dist/binaries/${{ matrix.service.name }}/${OUTPUT}.tar.gz" "${BINARY_NAME}"
355+
356+
- name: Upload binary artifact
357+
uses: actions/upload-artifact@v4
358+
with:
359+
name: binary-${{ matrix.service.name }}-${{ matrix.arch.goos }}-${{ matrix.arch.goarch }}
360+
path: dist/binaries/${{ matrix.service.name }}/*.tar.gz
361+
268362
manifest:
269363
name: Generate & Publish Manifest
270-
needs: [build-images, build-webapps, build-cli]
364+
needs: [build-images, build-webapps, build-cli, build-service-binaries]
271365
runs-on: ubuntu-latest
272366
steps:
273367
- uses: actions/checkout@v4
@@ -277,22 +371,121 @@ jobs:
277371
pattern: image-digest-*
278372
path: dist/digests
279373
merge-multiple: true
374+
375+
- name: Fetch MistServer metadata from GitHub Release
376+
id: mistserver
377+
run: |
378+
set -euo pipefail
379+
380+
# Fetch Docker metadata from MistServer GitHub Release
381+
BASE_URL="https://github.com/Livepeer-FrameWorks/mistserver/releases/download/${{ github.ref_name }}"
382+
383+
DIGEST=$(curl -sL "${BASE_URL}/docker-digest.txt" || echo "")
384+
TAG=$(curl -sL "${BASE_URL}/docker-tag.txt" || echo "")
385+
386+
if [[ -z "$DIGEST" || -z "$TAG" ]]; then
387+
echo "WARNING: Could not fetch MistServer metadata, using fallback"
388+
DIGEST="sha256:unknown"
389+
TAG="latest"
390+
fi
391+
392+
echo "digest=${DIGEST}" >> "$GITHUB_OUTPUT"
393+
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
394+
echo "Fetched MistServer metadata - Tag: ${TAG}, Digest: ${DIGEST}"
395+
280396
- name: Generate manifest
281397
run: |
282-
echo "platform_version: ${{ github.ref_name }}" > dist/manifest.yaml
283-
echo "git_commit: ${{ github.sha }}" >> dist/manifest.yaml
284-
echo "release_date: $(date -u '+%Y-%m-%dT%H:%M:%SZ')" >> dist/manifest.yaml
398+
set -euo pipefail
399+
400+
# Header
401+
cat > dist/manifest.yaml <<YAML
402+
platform_version: ${{ github.ref_name }}
403+
git_commit: ${{ github.sha }}
404+
release_date: $(date -u '+%Y-%m-%dT%H:%M:%SZ')
405+
406+
YAML
407+
408+
# Services (microservices with service_version field)
285409
echo "services:" >> dist/manifest.yaml
286410
for f in dist/digests/*.json; do
287411
name=$(jq -r .name "$f")
412+
# Skip webapp/website - they go in interfaces section
413+
if [[ "$name" == "webapp" || "$name" == "website" ]]; then
414+
continue
415+
fi
416+
288417
image=$(jq -r .image "$f")
289418
digest=$(jq -r .digest "$f")
290419
svcver=$(jq -r .service_version "$f")
291-
echo " - name: ${name}" >> dist/manifest.yaml
292-
echo " service_version: ${svcver}" >> dist/manifest.yaml
293-
echo " image: ${image}" >> dist/manifest.yaml
294-
echo " digest: ${digest}" >> dist/manifest.yaml
420+
421+
cat >> dist/manifest.yaml <<YAML
422+
- name: ${name}
423+
service_version: ${svcver}
424+
image: ${image}
425+
digest: ${digest}
426+
YAML
427+
done
428+
429+
# Native Binaries (for bare-metal deployment)
430+
echo "" >> dist/manifest.yaml
431+
echo "native_binaries:" >> dist/manifest.yaml
432+
for f in dist/digests/*.json; do
433+
name=$(jq -r .name "$f")
434+
# Skip webapp/website - they don't have native binaries
435+
if [[ "$name" == "webapp" || "$name" == "website" ]]; then
436+
continue
437+
fi
438+
439+
cat >> dist/manifest.yaml <<YAML
440+
- name: ${name}
441+
artifacts:
442+
- arch: linux-amd64
443+
file: frameworks-${name}-${{ github.ref_name }}-linux-amd64.tar.gz
444+
- arch: linux-arm64
445+
file: frameworks-${name}-${{ github.ref_name }}-linux-arm64.tar.gz
446+
YAML
295447
done
448+
449+
# Interfaces (webapp/website reference implementations)
450+
echo "" >> dist/manifest.yaml
451+
echo "interfaces:" >> dist/manifest.yaml
452+
for f in dist/digests/*.json; do
453+
name=$(jq -r .name "$f")
454+
# Only include webapp/website
455+
if [[ "$name" != "webapp" && "$name" != "website" ]]; then
456+
continue
457+
fi
458+
459+
image=$(jq -r .image "$f")
460+
digest=$(jq -r .digest "$f")
461+
462+
# Determine build dir and bundle name
463+
if [[ "$name" == "webapp" ]]; then
464+
bundle="webapp-build.tar.gz"
465+
else
466+
bundle="website-build.tar.gz"
467+
fi
468+
469+
cat >> dist/manifest.yaml <<YAML
470+
- name: ${name}
471+
image: ${image}
472+
digest: ${digest}
473+
static_bundle: ${bundle}
474+
YAML
475+
done
476+
477+
# External Dependencies (MistServer from separate repo)
478+
echo "" >> dist/manifest.yaml
479+
cat >> dist/manifest.yaml <<YAML
480+
external_dependencies:
481+
- name: mistserver
482+
image: docker.io/livepeerframeworks/mistserver:${{ steps.mistserver.outputs.tag }}
483+
digest: "${{ steps.mistserver.outputs.digest }}"
484+
YAML
485+
486+
# Infrastructure Requirements (from config/infrastructure.yaml)
487+
echo "" >> dist/manifest.yaml
488+
cat config/infrastructure.yaml >> dist/manifest.yaml
296489
- name: Upload manifest artifact
297490
uses: actions/upload-artifact@v4
298491
with:
@@ -304,6 +497,12 @@ jobs:
304497
pattern: cli-*
305498
path: dist/cli
306499
merge-multiple: true
500+
- name: Download service binary artifacts
501+
uses: actions/download-artifact@v4
502+
with:
503+
pattern: binary-*
504+
path: dist/binaries
505+
merge-multiple: true
307506
- name: Download webapp bundle
308507
uses: actions/download-artifact@v4
309508
with:
@@ -323,6 +522,7 @@ jobs:
323522
files: |
324523
dist/manifest.yaml
325524
dist/cli/*
525+
dist/binaries/*.tar.gz
326526
dist/webapp-build.tar.gz
327527
dist/website-build.tar.gz
328528
env:
@@ -369,25 +569,44 @@ jobs:
369569
# Commit and push
370570
git config user.name "github-actions"
371571
git config user.email "[email protected]"
372-
git checkout -b "${RELEASE_BRANCH}"
572+
573+
# Fetch branch if it exists
574+
git fetch origin "${RELEASE_BRANCH}" || true
575+
576+
# Create or reset to new content
577+
git checkout -B "${RELEASE_BRANCH}"
373578
git add releases/${{ github.ref_name }}.yaml channels/${channel}.yaml
374579
git commit -m "Release manifest for ${{ github.ref_name }}"
375-
git push origin "${RELEASE_BRANCH}"
580+
git push --force origin "${RELEASE_BRANCH}"
376581
377-
- name: Create PR to env repo
582+
- name: Create or update PR to env repo
378583
env:
379584
GH_TOKEN: ${{ secrets.GITOPS_REPO_TOKEN }}
380585
run: |
381586
cd env-repo
382-
gh pr create \
587+
588+
# Check if PR already exists
589+
PR_NUMBER=$(gh pr list \
383590
--repo "${{ env.ENV_REPO }}" \
384-
--base main \
385591
--head "${RELEASE_BRANCH}" \
386-
--title "Release ${{ github.ref_name }} manifest" \
387-
--body "This PR adds the release manifest for ${{ github.ref_name }}.
592+
--base main \
593+
--json number \
594+
--jq '.[0].number' 2>/dev/null || echo "")
595+
596+
if [[ -n "$PR_NUMBER" ]]; then
597+
echo "PR #${PR_NUMBER} already exists and was updated via branch push"
598+
echo "https://github.com/${{ env.ENV_REPO }}/pull/${PR_NUMBER}"
599+
else
600+
gh pr create \
601+
--repo "${{ env.ENV_REPO }}" \
602+
--base main \
603+
--head "${RELEASE_BRANCH}" \
604+
--title "Release ${{ github.ref_name }} manifest" \
605+
--body "This PR adds the release manifest for ${{ github.ref_name }}.
388606
389607
It maps each service to image@digest and includes component versions.
390608
391609
**Platform Version:** \`${{ github.ref_name }}\`
392610
**Git Commit:** \`${{ github.sha }}\`
393611
**Release Date:** \`$(date -u '+%Y-%m-%dT%H:%M:%SZ')\`"
612+
fi

api_gateway/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ COPY api_gateway/ ./
2020
ARG VERSION=dev
2121
ARG GIT_COMMIT=docker
2222
ARG BUILD_DATE
23-
ARG COMPONENT_NAME=gateway
23+
ARG COMPONENT_NAME=bridge
2424
ARG COMPONENT_VERSION=0.0.0
2525

2626
RUN go mod download

0 commit comments

Comments
 (0)