name: Release Nightly

on:
  schedule:
    # Fire every day at 7:00am UTC (Roughly before EU workday and after US workday)
    - cron: "0 7 * * *"
  push:
    tags:
      - "nightly"

env:
  CARGO_TERM_COLOR: always
  CARGO_INCREMENTAL: 0
  RUST_BACKTRACE: 1

jobs:
  style:
    timeout-minutes: 60
    name: Check formatting and Clippy lints
    if: github.repository_owner == 'zed-industries'
    runs-on:
      - self-hosted
      - macOS
    steps:
      - name: Checkout repo
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
        with:
          clean: false
          fetch-depth: 0

      - name: Run style checks
        uses: ./.github/actions/check_style

      - name: Run clippy
        run: ./script/clippy

  tests:
    timeout-minutes: 60
    name: Run tests
    if: github.repository_owner == 'zed-industries'
    runs-on:
      - self-hosted
      - macOS
    needs: style
    steps:
      - name: Checkout repo
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
        with:
          clean: false

      - name: Run tests
        uses: ./.github/actions/run_tests

  bundle-mac:
    timeout-minutes: 60
    name: Create a macOS bundle
    if: github.repository_owner == 'zed-industries'
    runs-on:
      - self-hosted
      - bundle
    needs: tests
    env:
      MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
      MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
      APPLE_NOTARIZATION_KEY: ${{ secrets.APPLE_NOTARIZATION_KEY }}
      APPLE_NOTARIZATION_KEY_ID: ${{ secrets.APPLE_NOTARIZATION_KEY_ID }}
      APPLE_NOTARIZATION_ISSUER_ID: ${{ secrets.APPLE_NOTARIZATION_ISSUER_ID }}
      DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}
      DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}
      ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
    steps:
      - name: Install Node
        uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
        with:
          node-version: "18"

      - name: Checkout repo
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
        with:
          clean: false

      - name: Set release channel to nightly
        run: |
          set -eu
          version=$(git rev-parse --short HEAD)
          echo "Publishing version: ${version} on release channel nightly"
          echo "nightly" > crates/zed/RELEASE_CHANNEL

      - name: Create macOS app bundle
        run: script/bundle-mac

      - name: Upload Zed Nightly
        run: script/upload-nightly macos

  bundle-linux-x86:
    timeout-minutes: 60
    name: Create a Linux *.tar.gz bundle for x86
    if: github.repository_owner == 'zed-industries'
    runs-on:
      - buildjet-16vcpu-ubuntu-2004
    needs: tests
    env:
      DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}
      DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}
      ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
    steps:
      - name: Checkout repo
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
        with:
          clean: false

      - name: Add Rust to the PATH
        run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH

      - name: Install Linux dependencies
        run: ./script/linux && ./script/install-mold 2.34.0

      - name: Limit target directory size
        run: script/clear-target-dir-if-larger-than 100

      - name: Set release channel to nightly
        run: |
          set -euo pipefail
          version=$(git rev-parse --short HEAD)
          echo "Publishing version: ${version} on release channel nightly"
          echo "nightly" > crates/zed/RELEASE_CHANNEL

      - name: Create Linux .tar.gz bundle
        run: script/bundle-linux

      - name: Upload Zed Nightly
        run: script/upload-nightly linux-targz

  bundle-linux-arm:
    timeout-minutes: 60
    name: Create a Linux *.tar.gz bundle for ARM
    if: github.repository_owner == 'zed-industries'
    runs-on:
      - buildjet-16vcpu-ubuntu-2204-arm
    needs: tests
    env:
      DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}
      DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}
      ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
    steps:
      - name: Checkout repo
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
        with:
          clean: false

      - name: Install Linux dependencies
        run: ./script/linux

      - name: Limit target directory size
        run: script/clear-target-dir-if-larger-than 100

      - name: Set release channel to nightly
        run: |
          set -euo pipefail
          version=$(git rev-parse --short HEAD)
          echo "Publishing version: ${version} on release channel nightly"
          echo "nightly" > crates/zed/RELEASE_CHANNEL

      - name: Create Linux .tar.gz bundle
        run: script/bundle-linux

      - name: Upload Zed Nightly
        run: script/upload-nightly linux-targz

  freebsd:
    timeout-minutes: 60
    if: github.repository_owner == 'zed-industries'
    runs-on: github-8vcpu-ubuntu-2404
    needs: tests
    name: Build Zed on FreeBSD
    # env:
    #   MYTOKEN : ${{ secrets.MYTOKEN }}
    #   MYTOKEN2: "value2"
    steps:
      - uses: actions/checkout@v4
      - name: Build FreeBSD remote-server
        id: freebsd-build
        uses: vmactions/freebsd-vm@c3ae29a132c8ef1924775414107a97cac042aad5 # v1.2.0
        with:
          # envs: "MYTOKEN MYTOKEN2"
          usesh: true
          release: 13.5
          copyback: true
          prepare: |
            pkg install -y \
              bash curl jq git \
              rustup-init cmake-core llvm-devel-lite pkgconf protobuf # ibx11 alsa-lib rust-bindgen-cli
          run: |
            freebsd-version
            sysctl hw.model
            sysctl hw.ncpu
            sysctl hw.physmem
            sysctl hw.usermem
            git config --global --add safe.directory /home/runner/work/zed/zed
            rustup-init --profile minimal --default-toolchain none -y
            . "$HOME/.cargo/env"
            ./script/bundle-freebsd
            mkdir -p out/
            mv "target/zed-remote-server-freebsd-x86_64.gz" out/
            rm -rf target/
            cargo clean

      - name: Upload Artifact to Workflow - zed-remote-server (run-bundling)
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
        if: contains(github.event.pull_request.labels.*.name, 'run-bundling')
        with:
          name: zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-x86_64-unknown-freebsd.gz
          path: out/zed-remote-server-freebsd-x86_64.gz

      - name: Upload Artifacts to release
        uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
        if: ${{ !(contains(github.event.pull_request.labels.*.name, 'run-bundling')) }}
        with:
          draft: true
          prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
          files: |
            out/zed-remote-server-freebsd-x86_64.gz
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  bundle-nix:
    name: Build and cache Nix package
    needs: tests
    uses: ./.github/workflows/nix.yml

  update-nightly-tag:
    name: Update nightly tag
    if: github.repository_owner == 'zed-industries'
    runs-on: ubuntu-latest
    needs:
      - bundle-mac
      - bundle-linux-x86
      - bundle-linux-arm
    steps:
      - name: Checkout repo
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
        with:
          fetch-depth: 0

      - name: Update nightly tag
        run: |
          if [ "$(git rev-parse nightly)" = "$(git rev-parse HEAD)" ]; then
            echo "Nightly tag already points to current commit. Skipping tagging."
            exit 0
          fi
          git config user.name github-actions
          git config user.email github-actions@github.com
          git tag -f nightly
          git push origin nightly --force
