component-image #673
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: Component image | |
| on: | |
| repository_dispatch: | |
| types: [component-image] | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| env: | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true | |
| concurrency: | |
| group: typetype-beta-coordination | |
| cancel-in-progress: false | |
| jobs: | |
| validate: | |
| runs-on: [self-hosted, Linux, X64, ci-stack] | |
| outputs: | |
| channel: ${{ steps.payload.outputs.channel }} | |
| component: ${{ steps.payload.outputs.component }} | |
| digest: ${{ steps.payload.outputs.digest }} | |
| image: ${{ steps.payload.outputs.image }} | |
| revision: ${{ steps.payload.outputs.revision }} | |
| version: ${{ steps.payload.outputs.version }} | |
| steps: | |
| - name: Validate payload | |
| id: payload | |
| env: | |
| EVENT_NAME: ${{ github.event_name }} | |
| PAYLOAD: ${{ toJSON(github.event.client_payload) }} | |
| run: | | |
| if [[ "$EVENT_NAME" == "workflow_dispatch" ]]; then | |
| { | |
| echo "channel=beta" | |
| echo "component=all" | |
| echo "digest=manual" | |
| echo "image=all beta images" | |
| echo "revision=$GITHUB_SHA" | |
| echo "version=manual" | |
| } >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| channel="$(jq -er '.channel' <<< "$PAYLOAD")" | |
| component="$(jq -er '.component' <<< "$PAYLOAD")" | |
| digest="$(jq -er '.digest' <<< "$PAYLOAD")" | |
| image="$(jq -er '.image' <<< "$PAYLOAD")" | |
| revision="$(jq -er '.revision' <<< "$PAYLOAD")" | |
| version="$(jq -er '.version' <<< "$PAYLOAD")" | |
| case "$component" in | |
| frontend) image_name="typetype" ;; | |
| server) image_name="typetype-server" ;; | |
| downloader) image_name="typetype-downloader" ;; | |
| token) image_name="typetype-token" ;; | |
| *) exit 64 ;; | |
| esac | |
| case "$channel" in | |
| beta) expected_image="ghcr.io/typetype-video/${image_name}-beta" ;; | |
| stable) expected_image="ghcr.io/typetype-video/${image_name}" ;; | |
| *) exit 64 ;; | |
| esac | |
| [[ "$image" == "$expected_image" ]] | |
| [[ "$digest" =~ ^sha256:[0-9a-f]{64}$ ]] | |
| [[ "$revision" =~ ^[0-9a-f]{40}$ ]] | |
| [[ "$version" =~ ^[0-9A-Za-z][0-9A-Za-z._+-]{0,127}$ ]] | |
| { | |
| echo "channel=$channel" | |
| echo "component=$component" | |
| echo "digest=$digest" | |
| echo "image=$image" | |
| echo "revision=$revision" | |
| echo "version=$version" | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Record component version | |
| env: | |
| CHANNEL: ${{ steps.payload.outputs.channel }} | |
| COMPONENT: ${{ steps.payload.outputs.component }} | |
| DIGEST: ${{ steps.payload.outputs.digest }} | |
| IMAGE: ${{ steps.payload.outputs.image }} | |
| REVISION: ${{ steps.payload.outputs.revision }} | |
| VERSION: ${{ steps.payload.outputs.version }} | |
| run: | | |
| { | |
| echo "## Component image" | |
| echo | |
| echo "- Channel: \`$CHANNEL\`" | |
| echo "- Component: \`$COMPONENT\`" | |
| echo "- Version: \`$VERSION\`" | |
| echo "- Revision: \`$REVISION\`" | |
| echo "- Image: \`$IMAGE@$DIGEST\`" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| deploy-beta: | |
| needs: validate | |
| if: needs.validate.outputs.channel == 'beta' | |
| runs-on: [self-hosted, Linux, X64, ci-stack] | |
| environment: beta | |
| steps: | |
| - name: Validate deployment configuration | |
| env: | |
| DEPLOY_HOST: ${{ secrets.TYPE_TYPE_DEPLOY_HOST }} | |
| DEPLOY_PORT: ${{ secrets.TYPE_TYPE_DEPLOY_PORT }} | |
| DEPLOY_USER: ${{ secrets.TYPE_TYPE_DEPLOY_USER }} | |
| DEPLOY_KEY: ${{ secrets.TYPE_TYPE_DEPLOY_SSH_KEY }} | |
| run: | | |
| test -n "$DEPLOY_HOST" | |
| test -n "$DEPLOY_PORT" | |
| test -n "$DEPLOY_USER" | |
| test -n "$DEPLOY_KEY" | |
| - name: Configure SSH | |
| env: | |
| DEPLOY_HOST: ${{ secrets.TYPE_TYPE_DEPLOY_HOST }} | |
| DEPLOY_PORT: ${{ secrets.TYPE_TYPE_DEPLOY_PORT }} | |
| DEPLOY_KEY: ${{ secrets.TYPE_TYPE_DEPLOY_SSH_KEY }} | |
| run: | | |
| install -m 600 /dev/null "$RUNNER_TEMP/typetype_deploy_key" | |
| printf '%s\n' "$DEPLOY_KEY" > "$RUNNER_TEMP/typetype_deploy_key" | |
| ssh-keyscan -p "$DEPLOY_PORT" "$DEPLOY_HOST" > "$RUNNER_TEMP/known_hosts" 2>/dev/null | |
| - name: Update beta | |
| env: | |
| COMPONENT: ${{ needs.validate.outputs.component }} | |
| DEPLOY_HOST: ${{ secrets.TYPE_TYPE_DEPLOY_HOST }} | |
| DEPLOY_PORT: ${{ secrets.TYPE_TYPE_DEPLOY_PORT }} | |
| DEPLOY_USER: ${{ secrets.TYPE_TYPE_DEPLOY_USER }} | |
| DIGEST: ${{ needs.validate.outputs.digest }} | |
| IMAGE: ${{ needs.validate.outputs.image }} | |
| run: | | |
| printf -v update_command \ | |
| 'TYPETYPE_DEPLOY_COMPONENT=%q TYPETYPE_DEPLOY_IMAGE=%q TYPETYPE_DEPLOY_DIGEST=%q /usr/local/sbin/typetype-beta-update' \ | |
| "$COMPONENT" "$IMAGE" "$DIGEST" | |
| ssh -i "$RUNNER_TEMP/typetype_deploy_key" -p "$DEPLOY_PORT" -o BatchMode=yes -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile="$RUNNER_TEMP/known_hosts" "$DEPLOY_USER@$DEPLOY_HOST" "$update_command" | |
| curl --fail --retry 12 --retry-delay 2 --retry-all-errors --silent --show-error https://beta.typetype.video/api/health | |
| curl --fail --retry 12 --retry-delay 2 --retry-all-errors --silent --show-error https://beta.typetype.video/api/downloader/health | |
| record-stable: | |
| needs: validate | |
| if: needs.validate.outputs.channel == 'stable' | |
| runs-on: [self-hosted, Linux, X64, ci-stack] | |
| steps: | |
| - run: echo "Stable image recorded; no deployment was started." |