# This file was generated by ci/generate and should not be modified by hand
---
name: Validate everything
'on':
  push:
  pull_request_target:
    types:
    - labeled
    branches:
    - main
env:
  DOCKER_HUB_USERNAME: shepmaster
  GH_CONTAINER_REGISTRY_USERNAME: shepmaster
  AWS_ACCESS_KEY_ID: AKIAWESVHZ3JQAY5NM5K
jobs:
  build_compiler_containers:
    name: Build ${{ matrix.channel }} compiler container
    runs-on: ubuntu-latest
    strategy:
      matrix:
        channel:
        - stable
        - beta
        - nightly
    if: 'github.event_name == ''push'' || contains(github.event.pull_request.labels.*.name, ''CI: approved'')'
    env:
      IMAGE_NAME: ghcr.io/integer32llc/rust-playground-ci-rust-${{ matrix.channel }}
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
      with:
        ref: "${{ github.event.pull_request.head.sha }}"
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v3
      with:
        driver-opts: image=moby/buildkit:v0.11.6
    - name: Login to GitHub Container Registry
      uses: docker/login-action@v3
      with:
        registry: ghcr.io
        username: "${{ env.GH_CONTAINER_REGISTRY_USERNAME }}"
        password: "${{ secrets.GH_CONTAINER_REGISTRY_TOKEN }}"
    - name: Build and push container
      uses: docker/build-push-action@v5
      with:
        context: compiler/base/
        file: compiler/base/Dockerfile
        build-args: channel=${{ matrix.channel }}
        push: true
        tags: "${{ env.IMAGE_NAME }}:${{ github.run_id }}"
        cache-from: type=gha,scope=${{ matrix.channel }}
        cache-to: type=gha,scope=${{ matrix.channel }},mode=max
  build_backend:
    name: Build backend
    runs-on: ubuntu-latest
    if: 'github.event_name == ''push'' || contains(github.event.pull_request.labels.*.name, ''CI: approved'')'
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
      with:
        ref: "${{ github.event.pull_request.head.sha }}"
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        components: rustfmt
    - name: Format server
      run: cargo fmt --manifest-path ui/Cargo.toml --all --check
    - name: Format top-crates
      run: cargo fmt --manifest-path top-crates/Cargo.toml --check
    - name: Format orchestrator
      run: cargo fmt --manifest-path compiler/base/orchestrator/Cargo.toml --check
    - name: Build backend
      run: "./ci/build-backend.sh"
    - name: Save backend artifact
      uses: actions/upload-artifact@v4
      with:
        name: backend
        path: |
          docker-output/ui
          docker-output/unit_tests_ui
          docker-output/unit_tests_orchestrator
  build_frontend:
    name: Build frontend
    runs-on: ubuntu-latest
    if: 'github.event_name == ''push'' || contains(github.event.pull_request.labels.*.name, ''CI: approved'')'
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
      with:
        ref: "${{ github.event.pull_request.head.sha }}"
    - name: Configure node
      uses: actions/setup-node@v4
      with:
        node-version: 22.2
    - name: Get pnpm version from package.json
      id: pnpm-version
      run: 'echo "pnpm_version=$(node -p ''require(`./ui/frontend/package.json`).engines.pnpm'')" >> $GITHUB_OUTPUT

        '
    - name: Install pnpm
      uses: pnpm/action-setup@v3
      with:
        version: "${{ steps.pnpm-version.outputs.pnpm_version }}"
    - name: Get pnpm store directory
      id: pnpm-cache-dir-path
      run: 'echo "dir=$(pnpm store path --silent)" >> $GITHUB_OUTPUT

        '
    - name: Cache pnpm intermediate products
      uses: actions/cache@v4
      with:
        path: "${{ steps.pnpm-cache-dir-path.outputs.dir }}"
        key: "${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}"
        restore-keys: "${{ runner.os }}-pnpm-\n"
    - name: Install dependencies
      run: pnpm --dir ui/frontend/ install
    - name: Run tests
      run: pnpm --dir ui/frontend/ run test
    - name: Lint
      run: pnpm --dir ui/frontend/ run test:lint
    - name: Style
      run: pnpm --dir ui/frontend/ run test:style
    - name: Build frontend
      run: pnpm --dir ui/frontend/ run build:production
    - name: Save frontend artifact
      uses: actions/upload-artifact@v4
      with:
        name: frontend
        path: ui/frontend/build
  run_integration_tests:
    name: Running integration tests
    runs-on: ubuntu-latest
    if: 'github.event_name == ''push'' || contains(github.event.pull_request.labels.*.name, ''CI: approved'')'
    needs:
    - build_compiler_containers
    - build_backend
    - build_frontend
    defaults:
      run:
        working-directory: tests
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
      with:
        ref: "${{ github.event.pull_request.head.sha }}"
    - name: Configure Ruby
      uses: ruby/setup-ruby@v1
      with:
        ruby-version: 3.0.2
    - name: Cache bundler intermediate products
      uses: actions/cache@v4
      with:
        path: tests/vendor/bundle
        key: "${{ runner.os }}-gems-${{ hashFiles('tests/**/Gemfile.lock') }}"
        restore-keys: "${{ runner.os }}-gems-"
    - name: Install gems
      run: |-
        gem install bundler
        bundle config path vendor/bundle
        bundle install --jobs 4 --retry 3
    - name: Pull containers
      run: echo ghcr.io/integer32llc/rust-playground-ci-rust-{stable,beta,nightly}:${{ github.run_id }} | xargs -n1 docker pull
    - name: Rename containers
      run: |-
        for c in stable beta nightly; do
          docker tag ghcr.io/integer32llc/rust-playground-ci-rust-$c:${{ github.run_id }} ghcr.io/integer32llc/rust-playground-ci-rust-$c
          docker tag ghcr.io/integer32llc/rust-playground-ci-rust-$c:${{ github.run_id }} shepmaster/rust-$c
          docker tag ghcr.io/integer32llc/rust-playground-ci-rust-$c:${{ github.run_id }} rust-$c
        done
    - name: Download backend
      uses: actions/download-artifact@v4
      with:
        name: backend
        path: tests/server/
    - name: Download frontend
      uses: actions/download-artifact@v4
      with:
        name: frontend
        path: tests/server/build/
    - name: Run orchestrator unit tests
      env:
        TESTS_MAX_CONCURRENCY: 3
        TESTS_TIMEOUT_MS: 30000
      run: chmod +x ./server/unit_tests_orchestrator && ./server/unit_tests_orchestrator
    - name: Run ui unit tests
      run: chmod +x ./server/unit_tests_ui && ./server/unit_tests_ui
    - name: Run tests
      env:
        PLAYGROUND_UI_ROOT: server/build/
        PLAYGROUND_CORS_ENABLED: true
        PLAYGROUND_GITHUB_TOKEN: "${{ secrets.PLAYGROUND_GITHUB_TOKEN }}"
      run: |-
        killall -q ui || true
        chmod +x ./server/ui && ./server/ui &
        bundle exec rspec
    - name: Preserve screenshots
      if: "${{ failure() }}"
      uses: actions/upload-artifact@v4
      with:
        name: test-failures
        path: tests/test-failures
  release_artifacts:
    name: Release artifacts
    runs-on: ubuntu-latest
    needs:
    - run_integration_tests
    if: github.event_name == 'push' && github.event.ref == 'refs/heads/main'
    permissions:
      contents: read
      id-token: write
    steps:
    - name: Login to GitHub Container Registry
      uses: docker/login-action@v3
      with:
        registry: ghcr.io
        username: "${{ env.GH_CONTAINER_REGISTRY_USERNAME }}"
        password: "${{ secrets.GH_CONTAINER_REGISTRY_TOKEN }}"
    - name: Login to Docker Hub
      uses: docker/login-action@v3
      with:
        username: "${{ env.DOCKER_HUB_USERNAME }}"
        password: "${{ secrets.DOCKER_HUB_TOKEN }}"
    - name: Pull containers
      run: echo ghcr.io/integer32llc/rust-playground-ci-rust-{stable,beta,nightly}:${{ github.run_id }} | xargs -n1 docker pull
    - name: Rename containers
      run: |-
        for c in stable beta nightly; do
          docker tag ghcr.io/integer32llc/rust-playground-ci-rust-$c:${{ github.run_id }} ghcr.io/integer32llc/rust-playground-ci-rust-$c
          docker tag ghcr.io/integer32llc/rust-playground-ci-rust-$c:${{ github.run_id }} shepmaster/rust-$c
          docker tag ghcr.io/integer32llc/rust-playground-ci-rust-$c:${{ github.run_id }} rust-$c
        done
    - name: Push containers
      run: |-
        for c in stable beta nightly; do
          docker push ghcr.io/integer32llc/rust-playground-ci-rust-$c
          docker push shepmaster/rust-$c
        done
    - name: Download backend
      uses: actions/download-artifact@v4
      with:
        name: backend
        path: server/
    - name: Download frontend
      uses: actions/download-artifact@v4
      with:
        name: frontend
        path: server/build/
    - name: Configure AWS credentials (i32)
      uses: aws-actions/configure-aws-credentials@v4
      with:
        aws-access-key-id: "${{ env.AWS_ACCESS_KEY_ID }}"
        aws-secret-access-key: "${{ secrets.AWS_SECRET_ACCESS_KEY }}"
        aws-region: us-east-2
    - name: Push backend (i32)
      run: aws s3 cp server/ui s3://playground-artifacts-i32
    - name: Push frontend (i32)
      run: aws s3 sync server/build/ s3://playground-artifacts-i32/build
    - name: Configure AWS credentials (rust-lang)
      uses: aws-actions/configure-aws-credentials@v4
      with:
        role-skip-session-tagging: true
        role-to-assume: arn:aws:iam::890664054962:role/upload-playground-artifacts
        aws-region: us-west-1
    - name: Push backend (rust-lang)
      run: aws s3 cp server/ui s3://rust-playground-artifacts
    - name: Push frontend (rust-lang)
      run: aws s3 sync server/build/ s3://rust-playground-artifacts/build