Merge pull request #20 from TypeType-Video/release/1.9.0 #144
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Docker | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - dev | |
| tags: | |
| - "v*" | |
| workflow_dispatch: | |
| env: | |
| REGISTRY: ghcr.io | |
| UPSTREAM_REPOSITORY: TypeType-Video/TypeType | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: docker-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| prepare: | |
| runs-on: [self-hosted, Linux, X64, ci-stack] | |
| outputs: | |
| build-time: ${{ steps.build-info.outputs.build-time }} | |
| image: ${{ steps.build-info.outputs.image }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| metadata-json: ${{ steps.meta.outputs.json }} | |
| platform-matrix: ${{ steps.build-info.outputs.platform-matrix }} | |
| version: ${{ steps.build-info.outputs.version }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 | |
| with: | |
| persist-credentials: false | |
| - name: Set up Bun | |
| uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 | |
| with: | |
| bun-version: 1.4.2 | |
| - name: Resolve build metadata | |
| id: build-info | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| if [[ "$GITHUB_REF" == refs/tags/v* ]]; then | |
| base_version="${GITHUB_REF_NAME#v}" | |
| if [[ ! "$base_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
| echo "Invalid component release tag: $GITHUB_REF_NAME" | |
| exit 1 | |
| fi | |
| gh api "repos/${UPSTREAM_REPOSITORY}/git/ref/tags/v${base_version}" >/dev/null | |
| version="$base_version" | |
| else | |
| upstream_tag="$(gh api "repos/${UPSTREAM_REPOSITORY}/releases/latest" --jq '.tag_name')" | |
| if [[ ! "$upstream_tag" =~ ^v([0-9]+\.[0-9]+\.[0-9]+)$ ]]; then | |
| echo "Invalid upstream TypeType release tag: $upstream_tag" | |
| exit 1 | |
| fi | |
| base_version="${BASH_REMATCH[1]}" | |
| fi | |
| if [[ "$GITHUB_REF_NAME" == "main" ]]; then | |
| version="$base_version" | |
| elif [[ "$GITHUB_REF_NAME" == "dev" ]]; then | |
| base_version="$(bun -e 'import packageJson from "./package.json"; console.log(packageJson.version)')" | |
| if [[ ! "$base_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
| echo "Invalid development version: $base_version" | |
| exit 1 | |
| fi | |
| version="$base_version-dev.$GITHUB_RUN_NUMBER" | |
| elif [[ "$GITHUB_REF" != refs/tags/v* ]]; then | |
| channel="${GITHUB_REF_NAME//[^0-9A-Za-z-]/-}" | |
| version="$base_version-$channel.$GITHUB_RUN_NUMBER" | |
| fi | |
| if [[ "$GITHUB_REF_NAME" == "dev" ]]; then | |
| image="${REGISTRY}/${GITHUB_REPOSITORY,,}-beta" | |
| else | |
| image="${REGISTRY}/${GITHUB_REPOSITORY,,}" | |
| fi | |
| { | |
| echo "image=$image" | |
| echo "version=$version" | |
| echo "build-time=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" | |
| } >> "$GITHUB_OUTPUT" | |
| if [[ "$GITHUB_REF_NAME" == "dev" ]]; then | |
| platform_matrix='{"include":[{"platform":"linux/amd64","arch":"amd64"}]}' | |
| else | |
| platform_matrix='{"include":[{"platform":"linux/amd64","arch":"amd64"},{"platform":"linux/arm64","arch":"arm64"}]}' | |
| fi | |
| echo "platform-matrix=$platform_matrix" >> "$GITHUB_OUTPUT" | |
| - name: Extract metadata | |
| id: meta | |
| uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 | |
| with: | |
| images: ${{ steps.build-info.outputs.image }} | |
| tags: | | |
| type=raw,value=${{ steps.build-info.outputs.version }} | |
| type=sha,prefix=sha-,format=short | |
| type=ref,event=branch | |
| type=ref,event=tag | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| type=raw,value=latest,enable=${{ github.ref_name == 'main' }} | |
| type=raw,value=latest,enable=${{ github.ref_name == 'dev' }} | |
| type=raw,value=beta,enable=${{ github.ref_name == 'dev' }} | |
| build-platform: | |
| needs: prepare | |
| runs-on: [self-hosted, Linux, X64, ci-stack] | |
| timeout-minutes: 45 | |
| permissions: | |
| contents: read | |
| packages: write | |
| strategy: | |
| fail-fast: false | |
| matrix: ${{ fromJSON(needs.prepare.outputs.platform-matrix) }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 | |
| with: | |
| persist-credentials: false | |
| - name: Isolate Docker credentials | |
| run: echo "DOCKER_CONFIG=$RUNNER_TEMP/docker-config" >> "$GITHUB_ENV" | |
| - name: Log in to GitHub Container Registry | |
| uses: docker/login-action@371161bbe7024a29a25c5e19bfcbc0804fe9ad2c | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Set up QEMU | |
| if: matrix.arch == 'arm64' | |
| uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 | |
| with: | |
| platforms: arm64 | |
| cache-image: false | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c | |
| - name: Build and push platform image | |
| id: build | |
| uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a | |
| with: | |
| context: . | |
| build-args: | | |
| BUILD_VERSION=${{ needs.prepare.outputs.version }} | |
| BUILD_REVISION=${{ github.sha }} | |
| BUILD_TIME=${{ needs.prepare.outputs.build-time }} | |
| platforms: ${{ matrix.platform }} | |
| labels: ${{ needs.prepare.outputs.labels }} | |
| outputs: type=image,name=${{ needs.prepare.outputs.image }},push-by-digest=true,name-canonical=true,push=true | |
| provenance: mode=max | |
| sbom: true | |
| cache-from: type=gha,scope=token-${{ matrix.arch }} | |
| cache-to: type=gha,mode=max,scope=token-${{ matrix.arch }} | |
| - name: Export digest | |
| env: | |
| DIGEST: ${{ steps.build.outputs.digest }} | |
| run: | | |
| digest_dir="$RUNNER_TEMP/token-digests" | |
| rm -rf "$digest_dir" | |
| mkdir -p "$digest_dir" | |
| touch "$digest_dir/${DIGEST#sha256:}" | |
| - name: Upload digest | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: token-digest-${{ matrix.arch }}-${{ github.run_id }}-${{ github.run_attempt }} | |
| path: ${{ runner.temp }}/token-digests/* | |
| if-no-files-found: error | |
| retention-days: 1 | |
| publish: | |
| needs: [prepare, build-platform] | |
| runs-on: [self-hosted, Linux, X64, ci-stack] | |
| timeout-minutes: 10 | |
| permissions: | |
| contents: read | |
| packages: write | |
| outputs: | |
| digest: ${{ steps.manifest.outputs.digest }} | |
| steps: | |
| - name: Isolate Docker credentials | |
| run: echo "DOCKER_CONFIG=$RUNNER_TEMP/docker-config" >> "$GITHUB_ENV" | |
| - name: Prepare digest directory | |
| run: rm -rf "$RUNNER_TEMP/token-digests" | |
| - name: Download digests | |
| uses: actions/download-artifact@v8 | |
| with: | |
| path: ${{ runner.temp }}/token-digests | |
| pattern: token-digest-*-${{ github.run_id }}-${{ github.run_attempt }} | |
| merge-multiple: true | |
| - name: Log in to GitHub Container Registry | |
| uses: docker/login-action@371161bbe7024a29a25c5e19bfcbc0804fe9ad2c | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c | |
| - name: Publish manifest list | |
| id: manifest | |
| env: | |
| DIGEST_DIR: ${{ runner.temp }}/token-digests | |
| IMAGE: ${{ needs.prepare.outputs.image }} | |
| METADATA_JSON: ${{ needs.prepare.outputs.metadata-json }} | |
| run: | | |
| mapfile -t digests < <(find "$DIGEST_DIR" -maxdepth 1 -type f -printf '%f\n' | sort) | |
| expected_digests=2 | |
| if [[ "$GITHUB_REF_NAME" == "dev" ]]; then expected_digests=1; fi | |
| if [[ "${#digests[@]}" -ne "$expected_digests" ]]; then | |
| echo "Expected $expected_digests platform digests, found ${#digests[@]}" | |
| exit 1 | |
| fi | |
| mapfile -t tags < <(jq -r '.tags[]' <<< "$METADATA_JSON") | |
| tag_args=() | |
| for tag in "${tags[@]}"; do tag_args+=(--tag "$tag"); done | |
| source_args=() | |
| for digest in "${digests[@]}"; do source_args+=("$IMAGE@sha256:$digest"); done | |
| docker buildx imagetools create "${tag_args[@]}" "${source_args[@]}" | |
| manifest_json="$(docker buildx imagetools inspect "${tags[0]}" --format '{{json .Manifest}}')" | |
| digest="$(jq -r '.digest' <<< "$manifest_json")" | |
| if [[ "$digest" != sha256:* ]]; then | |
| echo "Published manifest has no valid digest" | |
| exit 1 | |
| fi | |
| echo "digest=$digest" >> "$GITHUB_OUTPUT" | |
| notify-orchestrator: | |
| needs: [prepare, publish] | |
| if: github.ref_name == 'dev' || github.ref_name == 'main' || startsWith(github.ref, 'refs/tags/v') | |
| runs-on: [self-hosted, Linux, X64, ci-stack] | |
| permissions: | |
| contents: read | |
| env: | |
| GH_TOKEN: ${{ secrets.TYPETYPE_ORCHESTRATOR_TOKEN }} | |
| steps: | |
| - name: Send image digest | |
| env: | |
| DIGEST: ${{ needs.publish.outputs.digest }} | |
| IMAGE: ${{ needs.prepare.outputs.image }} | |
| VERSION: ${{ needs.prepare.outputs.version }} | |
| run: | | |
| if [[ "$GITHUB_REF_NAME" == "dev" ]]; then channel="beta"; else channel="stable"; fi | |
| jq -n \ | |
| --arg channel "$channel" \ | |
| --arg component "token" \ | |
| --arg digest "$DIGEST" \ | |
| --arg image "$IMAGE" \ | |
| --arg revision "$GITHUB_SHA" \ | |
| --arg version "$VERSION" \ | |
| '{event_type:"component-image",client_payload:{channel:$channel,component:$component,digest:$digest,image:$image,revision:$revision,version:$version}}' \ | |
| | gh api --method POST repos/TypeType-Video/TypeType/dispatches --input - |