Wire up release_nightly workflow, to upload artifacts to DO spaces

Max Brunsfeld , Kirill , and Mikayla created

Co-authored-by: Kirill <kirill@zed.dev>
Co-authored-by: Mikayla <mikayla@zed.dev>

Change summary

.github/actions/run_tests/action.yml  | 48 ++++++++++++++
.github/actions/rust_fmt/action.yml   | 21 ++++++
.github/workflows/ci.yml              | 49 --------------
.github/workflows/release_nightly.yml | 95 ++--------------------------
script/upload-nightly                 | 45 +++++-------
5 files changed, 100 insertions(+), 158 deletions(-)

Detailed changes

.github/actions/run_tests/action.yml 🔗

@@ -0,0 +1,48 @@
+name: 'Run tests'
+description: 'Runs the tests'
+
+runs:
+  using: "composite"
+  steps:
+    - name: Install Rust
+      shell: bash -euxo pipefail {0}
+      run: |
+        rustup set profile minimal
+        rustup update stable
+        rustup target add wasm32-wasi
+        cargo install cargo-nextest
+
+    - name: Install Node
+      uses: actions/setup-node@v3
+      with:
+        node-version: "18"
+
+    - name: Checkout repo
+      uses: actions/checkout@v3
+      with:
+        clean: false
+        submodules: "recursive"
+
+    - name: Limit target directory size
+      shell: bash -euxo pipefail {0}
+      run: script/clear-target-dir-if-larger-than 70
+
+    - name: Run check
+      env:
+        RUSTFLAGS: -D warnings
+      shell: bash -euxo pipefail {0}
+      run: cargo check --test --workspace
+
+    - name: Run tests
+      env:
+        RUSTFLAGS: -D warnings
+      shell: bash -euxo pipefail {0}
+      run: cargo nextest run --workspace --no-fail-fast
+
+    - name: Build collab
+      shell: bash -euxo pipefail {0}
+      run: cargo build -p collab
+
+    - name: Build other binaries
+      shell: bash -euxo pipefail {0}
+      run: cargo build --workspace --bins --all-features

.github/actions/rust_fmt/action.yml 🔗

@@ -0,0 +1,21 @@
+name: 'Run rustfmt'
+description: 'Runs rustfmt'
+
+runs:
+  using: "composite"
+  steps:
+    - name: Install Rust
+      shell: bash -euxo pipefail {0}
+      run: |
+        rustup set profile minimal
+        rustup update stable
+
+    - name: Checkout repo
+      uses: actions/checkout@v3
+      with:
+        clean: false
+        submodules: "recursive"
+
+    - name: cargo fmt
+      shell: bash -euxo pipefail {0}
+      run: cargo fmt --all -- --check

.github/workflows/ci.yml 🔗

@@ -23,19 +23,8 @@ jobs:
       - self-hosted
       - test
     steps:
-      - name: Install Rust
-        run: |
-          rustup set profile minimal
-          rustup update stable
-
-      - name: Checkout repo
-        uses: actions/checkout@v3
-        with:
-          clean: false
-          submodules: "recursive"
-
-      - name: cargo fmt
-        run: cargo fmt --all -- --check
+      - name: Run rustfmt
+        uses: ./.github/actions/rust_fmt
 
   tests:
     name: Run tests
@@ -43,41 +32,9 @@ jobs:
       - self-hosted
       - test
     needs: rustfmt
-    env:
-      RUSTFLAGS: -D warnings
     steps:
-      - name: Install Rust
-        run: |
-          rustup set profile minimal
-          rustup update stable
-          rustup target add wasm32-wasi
-          cargo install cargo-nextest
-
-      - name: Install Node
-        uses: actions/setup-node@v3
-        with:
-          node-version: "18"
-
-      - name: Checkout repo
-        uses: actions/checkout@v3
-        with:
-          clean: false
-          submodules: "recursive"
-
-      - name: Limit target directory size
-        run: script/clear-target-dir-if-larger-than 70
-
-      - name: Run check
-        run: cargo check --workspace
-
       - name: Run tests
-        run: cargo nextest run --workspace --no-fail-fast
-
-      - name: Build collab
-        run: cargo build -p collab
-
-      - name: Build other binaries
-        run: cargo build --workspace --bins --all-features
+        uses: ./.github/actions/run_tests
 
   bundle:
     name: Bundle app

.github/workflows/release_nightly.yml 🔗

@@ -20,19 +20,8 @@ jobs:
       - self-hosted
       - test
     steps:
-      - name: Install Rust
-        run: |
-          rustup set profile minimal
-          rustup update stable
-
-      - name: Checkout repo
-        uses: actions/checkout@v3
-        with:
-          clean: false
-          submodules: "recursive"
-
-      - name: cargo fmt
-        run: cargo fmt --all -- --check
+      - name: Run rustfmt
+        uses: ./.github/actions/rust_fmt
 
   tests:
     name: Run tests
@@ -40,41 +29,9 @@ jobs:
       - self-hosted
       - test
     needs: rustfmt
-    env:
-      RUSTFLAGS: -D warnings
     steps:
-      - name: Install Rust
-        run: |
-          rustup set profile minimal
-          rustup update stable
-          rustup target add wasm32-wasi
-          cargo install cargo-nextest
-
-      - name: Install Node
-        uses: actions/setup-node@v3
-        with:
-          node-version: "18"
-
-      - name: Checkout repo
-        uses: actions/checkout@v3
-        with:
-          clean: false
-          submodules: "recursive"
-
-      - name: Limit target directory size
-        run: script/clear-target-dir-if-larger-than 70
-
-      - name: Run check
-        run: cargo check --workspace
-
       - name: Run tests
-        run: cargo nextest run --workspace --no-fail-fast
-
-      - name: Build collab
-        run: cargo build -p collab
-
-      - name: Build other binaries
-        run: cargo build --workspace --bins --all-features
+        uses: ./.github/actions/run_tests
 
   bundle:
     name: Bundle app
@@ -87,6 +44,8 @@ jobs:
       MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
       APPLE_NOTARIZATION_USERNAME: ${{ secrets.APPLE_NOTARIZATION_USERNAME }}
       APPLE_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
+      DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}
+      DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}
     steps:
       - name: Install Rust
         run: |
@@ -110,22 +69,12 @@ jobs:
       - name: Limit target directory size
         run: script/clear-target-dir-if-larger-than 70
 
-      - name: Determine version and release channel
+      - name: Set release channel to nightly
         run: |
           set -eu
-
           version=$(git rev-parse --short HEAD)
-          channel=$(cat crates/zed/RELEASE_CHANNEL)
-          echo "Publishing version: ${version} on release channel ${channel}"
-          echo "RELEASE_CHANNEL=${channel}" >> $GITHUB_ENV
-
-          case ${channel} in
-            nightly)
-              exit 0;;
-            *)
-              echo "can't publish a release on channel ${channel} with this action"
-              exit 1;;
-          esac
+          echo "Publishing version: ${version} on release channel nightly"
+          echo "nightly" > crates/zed/RELEASE_CHANNEL
 
       - name: Generate license file
         run: script/generate-licenses
@@ -133,31 +82,5 @@ jobs:
       - name: Create app bundle
         run: script/bundle
 
-      # So, here's an example of how this _could_ be done.
-      # Problem: Need to setup some docker secrets
-      # Problem: This action is very old
-      # Problem: Need to add stuff for interacting with our API
-      # - uses: BetaHuhn/do-spaces-action@v2
-      #   name: Upload app bundle to nightly
-      #   id: spaces-upload
-      #   with:
-      #     # Need to put this stuff in kuberenetes I think
-      #     access_key: ${{ secrets.ACCESS_KEY}}
-      #     secret_key: ${{ secrets.SECRET_KEY }}
-      #     space_name: ${{ secrets.SPACE_NAME }}
-      #     space_region: ${{ secrets.SPACE_REGION }}
-      #     source: target/release/Zed.dmg
-      #   env:
-      #     GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
       - name: Upload Zed Nightly
-        run: script/upload-nightly #something something
-        with:
-          do_secret: ${{ secrets.DO_SPACES_SECRET }}
-          do_access_key: ${{ secrets.DO_SPACES_ACCESS_KEY }}
-
-      # Upload to zed.dev?
-      - name: Upload new release URL to zed.dev
-        run: ??? #something something
-        with:
-          nightly_release_key: ${{ secrets.NIGHTLY_RELEASE_KEY }}
-          deployment_url: ${{ steps.spaces-upload.outputs.output_url }}
+        run: script/upload-nightly

script/upload-nightly 🔗

@@ -1,44 +1,37 @@
 #!/bin/bash
 
 # Based on the template in: https://docs.digitalocean.com/reference/api/spaces-api/
-
+set -ux
 
 # Step 1: Define the parameters for the Space you want to upload to.
 SPACE="zed-nightly-host" # Find your endpoint in the control panel, under Settings.
 REGION="nyc3" # Must be "us-east-1" when creating new Spaces. Otherwise, use the region in your endpoint (e.g. nyc3).
-STORAGETYPE="STANDARD" # Storage type, can be STANDARD, REDUCED_REDUNDANCY, etc.
-KEY="???????" # Access key pair. You can create access key pairs using the control panel or API.
-SECRET="$SECRET" # Secret access key defined through an environment variable.
 
 # Step 2: Define a function that uploads your object via cURL.
-function putS3
+function uploadToSpaces
 {
-  path="." # The local path to the file you want to upload.
-  file="hello-world.txt" # The file you want to upload.
-  space_path="/" # The path within your Space where you want to upload the new file.
-  space="${SPACE}"
+  file_to_upload="$1"
+  file_name="$2"
+  space_path="nightly"
   date=$(date +"%a, %d %b %Y %T %z")
-  acl="x-amz-acl:private" # Defines Access-control List (ACL) permissions, such as private or public.
-  content_type="text/plain" # Defines the type of content you are uploading.
-  storage_type="x-amz-storage-class:${STORAGETYPE}"
-  string="PUT\n\n$content_type\n$date\n$acl\n$storage_type\n/$space$space_path$file"
-  signature=$(echo -en "${string}" | openssl sha1 -hmac "${SECRET}" -binary | base64)
-  curl -s -X PUT -T "$path/$file" \ # The cURL command that uploads your file.
-    -H "Host: $space.${REGION}.digitaloceanspaces.com" \
+  acl="x-amz-acl:private"
+  content_type="application/octet-stream"
+  storage_type="x-amz-storage-class:STANDARD"
+  string="PUT\n\n${content_type}\n${date}\n${acl}\n${storage_type}\n/${SPACE}/${space_path}/${file_name}"
+  signature=$(echo -en "${string}" | openssl sha1 -hmac "${DIGITALOCEAN_SPACES_SECRET_KEY}" -binary | base64)
+
+  curl -vv -s -X PUT -T "$file_to_upload" \
+    -H "Host: ${SPACE}.${REGION}.digitaloceanspaces.com" \
     -H "Date: $date" \
     -H "Content-Type: $content_type" \
     -H "$storage_type" \
     -H "$acl" \
-    -H "Authorization: AWS ${KEY}:$signature" \
-    "https://$space.${REGION}.digitaloceanspaces.com$space_path$file"
+    -H "Authorization: AWS ${DIGITALOCEAN_SPACES_ACCESS_KEY}:$signature" \
+    "https://${SPACE}.${REGION}.digitaloceanspaces.com/${space_path}/${file_name}"
 }
 
-# Step 3: mkdir for file based on release sha
-# :/sha-of- -commit/Zed.dmg
-
-# Step 4: Put Zed.dmg in that directory
-for file in "$path"/*; do
-  putS3 "$path" "${file##*/}" "nyc-tutorial-space/"
-done
+sha=$(git rev-parse HEAD)
+echo ${sha} > target/latest-sha
 
-# Step 5: Output that directory for next step
+uploadToSpaces "target/release/Zed.dmg" "Zed.dmg"
+uploadToSpaces "target/latest-sha" "latest-sha"