name: deploy app on: push: branches: - main - canary paths: - fluxer_app/** - fluxer_app_proxy/** - .github/workflows/deploy-app.yaml workflow_dispatch: inputs: channel: type: choice options: - stable - canary default: stable description: Release channel to deploy ref: type: string required: false default: '' description: Optional git ref (defaults to the triggering branch) concurrency: group: deploy-fluxer-app-${{ github.event_name == 'workflow_dispatch' && inputs.channel || (github.ref_name == 'canary' && 'canary') || 'stable' }} cancel-in-progress: true permissions: contents: write jobs: channel-vars: uses: ./.github/workflows/channel-vars.yaml with: github_event_name: ${{ github.event_name }} github_ref_name: ${{ github.ref_name }} workflow_dispatch_channel: ${{ github.event_name == 'workflow_dispatch' && inputs.channel || '' }} deploy: name: Deploy app needs: channel-vars runs-on: blacksmith-8vcpu-ubuntu-2404 timeout-minutes: 25 env: CHANNEL: ${{ needs.channel-vars.outputs.channel }} IS_CANARY: ${{ needs.channel-vars.outputs.is_canary }} STACK_SUFFIX: ${{ needs.channel-vars.outputs.stack_suffix }} SERVICE_NAME: ${{ format('fluxer-app{0}', needs.channel-vars.outputs.stack_suffix) }} DOCKERFILE: fluxer_app_proxy/Dockerfile CACHE_SCOPE: ${{ format('fluxer-app{0}', needs.channel-vars.outputs.stack_suffix) }} RELEASE_CHANNEL: ${{ needs.channel-vars.outputs.channel }} APP_REPLICAS: ${{ needs.channel-vars.outputs.is_canary == 'true' && 1 || 2 }} steps: - uses: actions/checkout@v6 with: ref: ${{ inputs.ref || '' }} fetch-depth: 0 - name: Set up pnpm uses: pnpm/action-setup@v4 - name: Set up Node.js uses: actions/setup-node@v6 with: node-version: 24 cache: pnpm cache-dependency-path: fluxer_app/pnpm-lock.yaml - name: Install dependencies run: python3 scripts/ci/workflows/deploy_app.py --step install_dependencies - name: Run Lingui i18n tasks run: python3 scripts/ci/workflows/deploy_app.py --step run_lingui env: TURBO_API: https://turborepo.fluxer.dev TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} TURBO_TEAM: team_fluxer - name: Record deploy commit run: python3 scripts/ci/workflows/deploy_app.py --step record_deploy_commit - name: Set up Rust uses: dtolnay/rust-toolchain@stable with: targets: wasm32-unknown-unknown - name: Cache Rust dependencies uses: actions/cache@v5 with: path: | ~/.cargo/bin/ ~/.cargo/registry/index/ ~/.cargo/registry/cache/ ~/.cargo/git/db/ fluxer_app/crates/gif_wasm/target/ key: ${{ runner.os }}-cargo-${{ hashFiles('fluxer_app/crates/gif_wasm/Cargo.lock') }} restore-keys: | ${{ runner.os }}-cargo- - name: Install wasm-pack run: python3 scripts/ci/workflows/deploy_app.py --step install_wasm_pack - name: Generate wasm artifacts run: python3 scripts/ci/workflows/deploy_app.py --step generate_wasm env: TURBO_API: https://turborepo.fluxer.dev TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} TURBO_TEAM: team_fluxer - name: Set up SSH agent uses: webfactory/ssh-agent@v0.9.1 with: ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY_SERVER }} - name: Add server to known hosts run: python3 scripts/ci/workflows/deploy_app.py --step add_known_hosts --server-ip ${{ secrets.SERVER_IP }} - name: Fetch deployment config env: SERVER: ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }} RELEASE_CHANNEL: ${{ env.RELEASE_CHANNEL }} run: python3 scripts/ci/workflows/deploy_app.py --step fetch_deployment_config - name: Build application env: FLUXER_CONFIG: ${{ github.workspace }}/fluxer_app/config.json TURBO_API: https://turborepo.fluxer.dev TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} TURBO_TEAM: team_fluxer run: python3 scripts/ci/workflows/deploy_app.py --step build_application - name: Install rclone run: python3 scripts/ci/workflows/deploy_app.py --step install_rclone - name: Upload assets to S3 static bucket env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} run: python3 scripts/ci/workflows/deploy_app.py --step upload_assets - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Login to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} - name: Set build timestamp run: python3 scripts/ci/workflows/deploy_app.py --step set_build_timestamp - name: Build image uses: docker/build-push-action@v6 with: context: . file: ${{ env.DOCKERFILE }} tags: ${{ env.SERVICE_NAME }}:${{ env.DEPLOY_SHA }} load: true platforms: linux/amd64 cache-from: type=gha,scope=${{ env.CACHE_SCOPE }} cache-to: type=gha,mode=max,scope=${{ env.CACHE_SCOPE }} build-args: | BUILD_SHA=${{ env.DEPLOY_SHA }} BUILD_NUMBER=${{ github.run_number }} BUILD_TIMESTAMP=${{ env.BUILD_TIMESTAMP }} RELEASE_CHANNEL=${{ env.RELEASE_CHANNEL }} env: DOCKER_BUILD_SUMMARY: false DOCKER_BUILD_RECORD_UPLOAD: false - name: Install docker-pussh run: python3 scripts/ci/workflows/deploy_app.py --step install_docker_pussh - name: Push image and deploy env: IMAGE_TAG: ${{ env.SERVICE_NAME }}:${{ env.DEPLOY_SHA }} SERVER: ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }} SERVICE_NAME: ${{ env.SERVICE_NAME }} COMPOSE_STACK: ${{ env.SERVICE_NAME }} RELEASE_CHANNEL: ${{ env.RELEASE_CHANNEL }} APP_REPLICAS: ${{ env.APP_REPLICAS }} run: python3 scripts/ci/workflows/deploy_app.py --step push_and_deploy