From 481ff6513500a961f28f1f58796ba4b997d1ba35 Mon Sep 17 00:00:00 2001 From: Hien To Date: Sun, 16 Jun 2024 14:01:43 +0700 Subject: [PATCH] Add nightly build for cortex to pull latest nightly of cortex.llamacpp --- .github/workflows/nightly-build.yml | 238 ++++++++++++++++++++++++++++ .github/workflows/nightly.yml | 158 ++++++++++++++++++ 2 files changed, 396 insertions(+) create mode 100644 .github/workflows/nightly-build.yml create mode 100644 .github/workflows/nightly.yml diff --git a/.github/workflows/nightly-build.yml b/.github/workflows/nightly-build.yml new file mode 100644 index 000000000..39b20a117 --- /dev/null +++ b/.github/workflows/nightly-build.yml @@ -0,0 +1,238 @@ +name: CI Cortex CPP + +on: + push: + tags: ["v[0-9]+.[0-9]+.[0-9]+-[0-9]+.[0-9]+.[0-9]+"] + paths: + [ + "cortex-cpp/**", + ] + workflow_dispatch: + +env: + LLM_MODEL_URL: https://delta.jan.ai/tinyllama-1.1b-chat-v0.3.Q2_K.gguf + EMBEDDING_MODEL_URL: https://catalog.jan.ai/dist/models/embeds/nomic-embed-text-v1.5.f16.gguf + +jobs: + create-draft-release: + runs-on: ubuntu-latest + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') + outputs: + upload_url: ${{ steps.create_release.outputs.upload_url }} + version: ${{ steps.get_version.outputs.version }} + permissions: + contents: write + steps: + - name: Extract tag name without v prefix + id: get_version + run: | + echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV && echo "::set-output name=version::${GITHUB_REF#refs/tags/v}" + env: + GITHUB_REF: ${{ github.ref }} + - name: Create Draft Release + id: create_release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ github.ref_name }} + token: ${{ secrets.GITHUB_TOKEN }} + name: "${{ env.VERSION }}" + draft: false + generate_release_notes: true + prerelease: true + + build-and-test: + runs-on: ${{ matrix.runs-on }} + needs: [create-draft-release] + timeout-minutes: 40 + strategy: + fail-fast: false + matrix: + include: + - os: "linux" + name: "amd64-avx2" + runs-on: "ubuntu-18-04" + cmake-flags: "-DLLAMA_AVX2=ON -DLLAMA_NATIVE=OFF" + run-e2e: true + + - os: "linux" + name: "amd64-avx" + runs-on: "ubuntu-18-04" + cmake-flags: "-DLLAMA_AVX2=OFF -DLLAMA_NATIVE=OFF" + run-e2e: false + + - os: "linux" + name: "amd64-avx512" + runs-on: "ubuntu-18-04" + cmake-flags: "-DLLAMA_AVX512=ON -DLLAMA_NATIVE=OFF" + run-e2e: false + + - os: "linux" + name: "amd64-vulkan" + runs-on: "ubuntu-18-04-cuda-11-7" + cmake-flags: "-DLLAMA_VULKAN=ON -DLLAMA_NATIVE=OFF" + run-e2e: false + + - os: "linux" + name: "amd64-cuda-11-7" + runs-on: "ubuntu-18-04-cuda-11-7" + cmake-flags: "-DCUDA_11_7=ON -DLLAMA_NATIVE=OFF -DLLAMA_CUDA=ON" + run-e2e: false + + - os: "linux" + name: "amd64-cuda-12-0" + runs-on: "ubuntu-18-04-cuda-12-0" + cmake-flags: "-DCUDA_12_0=ON -DLLAMA_NATIVE=OFF -DLLAMA_CUDA=ON" + run-e2e: false + + - os: "mac" + name: "amd64" + runs-on: "macos-13" + cmake-flags: "" + run-e2e: true + + - os: "mac" + name: "arm64" + runs-on: "macos-latest" + cmake-flags: "-DMAC_ARM64=ON" + run-e2e: false + + - os: "windows" + name: "amd64-avx2" + runs-on: "windows-cuda-12-0" + cmake-flags: "-DLLAMA_AVX2=ON -DLLAMA_NATIVE=OFF -DLLAMA_BUILD_SERVER=ON -DLLAMA_BLAS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=RELEASE" + run-e2e: true + + - os: "windows" + name: "amd64-avx" + runs-on: "windows-cuda-12-0" + cmake-flags: "-DLLAMA_AVX2=OFF -DLLAMA_NATIVE=OFF -DLLAMA_BUILD_SERVER=ON -DLLAMA_BLAS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=RELEASE" + run-e2e: false + + - os: "windows" + name: "amd64-avx512" + runs-on: "windows-cuda-12-0" + cmake-flags: "-DLLAMA_AVX512=ON -DLLAMA_NATIVE=OFF -DLLAMA_BUILD_SERVER=ON -DLLAMA_BLAS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=RELEASE" + run-e2e: false + + - os: "windows" + name: "amd64-vulkan" + runs-on: "windows-cuda-12-0" + cmake-flags: "-DLLAMA_VULKAN=ON -DLLAMA_NATIVE=OFF -DLLAMA_BUILD_SERVER=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=RELEASE" + run-e2e: false + + - os: "windows" + name: "amd64-avx2-cuda-12-0" + runs-on: "windows-cuda-12-0" + cmake-flags: "-DLLAMA_AVX2=ON -DLLAMA_NATIVE=OFF -DCUDA_12_0=ON -DLLAMA_BUILD_SERVER=ON -DLLAMA_CUDA=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=RELEASE" + run-e2e: false + + - os: "windows" + name: "amd64-avx-cuda-12-0" + runs-on: "windows-cuda-12-0" + cmake-flags: "-DLLAMA_AVX2=OFF -DLLAMA_NATIVE=OFF -DCUDA_12_0=ON -DLLAMA_BUILD_SERVER=ON -DLLAMA_CUDA=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=RELEASE" + run-e2e: false + + - os: "windows" + name: "amd64-avx512-cuda-12-0" + runs-on: "windows-cuda-12-0" + cmake-flags: "-DLLAMA_AVX512=ON -DLLAMA_NATIVE=OFF -DCUDA_12_0=ON -DLLAMA_BUILD_SERVER=ON -DLLAMA_CUDA=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=RELEASE" + run-e2e: false + + - os: "windows" + name: "amd64-avx2-cuda-11-7" + runs-on: "windows-cuda-11-7" + cmake-flags: "-DLLAMA_AVX2=ON -DLLAMA_NATIVE=OFF -DCUDA_11_7=ON -DLLAMA_BUILD_SERVER=ON -DLLAMA_CUDA=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=RELEASE" + run-e2e: false + + - os: "windows" + name: "amd64-avx-cuda-11-7" + runs-on: "windows-cuda-11-7" + cmake-flags: "-DLLAMA_AVX2=OFF -DLLAMA_NATIVE=OFF -DCUDA_11_7=ON -DLLAMA_BUILD_SERVER=ON -DLLAMA_CUDA=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=RELEASE" + run-e2e: false + - os: "windows" + name: "amd64-avx512-cuda-11-7" + runs-on: "windows-cuda-11-7" + cmake-flags: "-DLLAMA_AVX512=ON -DLLAMA_NATIVE=OFF -DCUDA_11_7=ON -DLLAMA_BUILD_SERVER=ON -DLLAMA_CUDA=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=RELEASE" + run-e2e: false + + steps: + - name: Clone + id: checkout + uses: actions/checkout@v3 + with: + submodules: recursive + + - uses: actions/setup-dotnet@v3 + if: runner.os == 'Windows' + with: + dotnet-version: "8.0.x" + + - name: Install choco on Windows + if: runner.os == 'Windows' + run: | + choco install make -y + + - name: Get Cer for code signing + if: runner.os == 'macOS' + run: base64 -d <<< "$CODE_SIGN_P12_BASE64" > /tmp/codesign.p12 + shell: bash + env: + CODE_SIGN_P12_BASE64: ${{ secrets.CODE_SIGN_P12_BASE64 }} + + - uses: apple-actions/import-codesign-certs@v2 + if: runner.os == 'macOS' + with: + p12-file-base64: ${{ secrets.CODE_SIGN_P12_BASE64 }} + p12-password: ${{ secrets.CODE_SIGN_P12_PASSWORD }} + + - name: Build + run: | + cd cortex-cpp + make build CMAKE_EXTRA_FLAGS="${{ matrix.cmake-flags }}" + + - name: Pre-package + run: | + cd cortex-cpp + make pre-package + + - name: Code Signing macOS + if: runner.os == 'macOS' + run: | + cd cortex-cpp + make codesign CODE_SIGN=true DEVELOPER_ID="${{ secrets.DEVELOPER_ID }}" + + - name: Code Signing Windows + if: runner.os == 'Windows' + shell: cmd + run: | + cd cortex-cpp + set PATH=%PATH%;%USERPROFILE%\.dotnet\tools + make codesign CODE_SIGN=true AZURE_KEY_VAULT_URI="${{ secrets.AZURE_KEY_VAULT_URI }}" AZURE_CLIENT_ID="${{ secrets.AZURE_CLIENT_ID }}" AZURE_TENANT_ID="${{ secrets.AZURE_TENANT_ID }}" AZURE_CLIENT_SECRET="${{ secrets.AZURE_CLIENT_SECRET }}" AZURE_CERT_NAME="${{ secrets.AZURE_CERT_NAME }}" + + + - name: Package + run: | + cd cortex-cpp + make package + + - name: Run e2e testing + if: ${{ matrix.run-e2e }} + run: | + cd cortex-cpp + make run-e2e-test RUN_TESTS=true LLM_MODEL_URL=${{ env.LLM_MODEL_URL }} EMBEDDING_MODEL_URL=${{ env.EMBEDDING_MODEL_URL }} + + - name: Upload Artifact + uses: actions/upload-artifact@v2 + with: + name: cortex-cpp-${{ matrix.os }}-${{ matrix.name }} + path: ./cortex-cpp/cortex-cpp + + - uses: actions/upload-release-asset@v1.0.1 + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ needs.create-draft-release.outputs.upload_url }} + asset_path: ./cortex-cpp/cortex-cpp.tar.gz + asset_name: cortex-cpp-${{ needs.create-draft-release.outputs.version }}-${{ matrix.os }}-${{ matrix.name }}.tar.gz + asset_content_type: application/gzip diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml new file mode 100644 index 000000000..93c634981 --- /dev/null +++ b/.github/workflows/nightly.yml @@ -0,0 +1,158 @@ +name: Nightly Update cortex.llamacpp + +on: + schedule: + - cron: '30 18 * * 1-5' # At 01:30 on every day-of-week from Monday through Friday UTC +7 + workflow_dispatch: + +jobs: + update-submodule: + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + actions: write + + outputs: + pr_number: ${{ steps.check-update.outputs.pr_number }} + pr_created: ${{ steps.check-update.outputs.pr_created }} + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + submodules: recursive + ref: dev + fetch-depth: 0 + token: ${{ secrets.PAT_SERVICE_ACCOUNT }} + + - name: Configure Git + run: | + git config --global user.name 'github-actions[bot]' + git config --global user.email 'github-actions[bot]@users.noreply.github.com' + + - name: Update submodule to latest release + id: check-update + env: + GITHUB_TOKEN: ${{ secrets.PAT_SERVICE_ACCOUNT }} + run: | + cd cortex-cpp + latest_prerelease_name=$(curl -s https://api.github.com/repos/janhq/cortex.llamacpp/releases | jq -r '.[] | select(.prerelease) | .name' | head -n 1) + + engine_cmake_path="engines/cortex.llamacpp/engine.cmake" + current_version=$(grep -oP 'set\(VERSION \K[^\)]+' "$engine_cmake_path") + + if [ "$current_version" = "$latest_prerelease_name" ]; then + echo "cortex.llamacpp remote repo doesn't have update today, skip nightly build" + echo "::set-output name=pr_created::false" + exit 0 + fi + sed -i "s/set(VERSION $current_version)/set(VERSION $latest_prerelease_name)/" "$engine_cmake_path" + echo "Updated version from $current_version to $latest_prerelease_name." + echo "::set-output name=pr_created::true" + cd - + git add $engine_cmake_path + git commit -m "Update cortex.llamacpp nightly to version $latest_prerelease_name" + branch_name="update-nightly-$(date +'%Y-%m-%d-%H-%M')" + git checkout -b $branch_name + git push origin $branch_name + + pr_title="Update cortex.llamacpp nightly to version $latest_prerelease_name" + pr_body="This PR updates the Update cortex.llamacpp nightly to version $latest_prerelease_name" + + gh pr create --title "$pr_title" --body "$pr_body" --head $branch_name --base dev --reviewer vansangpfiev + + pr_number=$(gh pr list --head $branch_name --json number --jq '.[0].number') + echo "::set-output name=pr_number::$pr_number" + + check-and-merge-pr: + needs: update-submodule + if: needs.update-submodule.outputs.pr_created == 'true' + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + submodules: recursive + fetch-depth: 0 + token: ${{ secrets.PAT_SERVICE_ACCOUNT }} + + - name: Wait for CI to pass + env: + GITHUB_TOKEN: ${{ secrets.PAT_SERVICE_ACCOUNT }} + run: | + pr_number=${{ needs.update-submodule.outputs.pr_number }} + while true; do + ci_completed=$(gh pr checks $pr_number --json completedAt --jq '.[].completedAt') + if echo "$ci_completed" | grep -q "0001-01-01T00:00:00Z"; then + echo "CI is still running, waiting..." + sleep 60 + else + echo "CI has completed, checking states..." + ci_states=$(gh pr checks $pr_number --json state --jq '.[].state') + if echo "$ci_states" | grep -vqE "SUCCESS|SKIPPED"; then + echo "CI failed, exiting..." + exit 1 + else + echo "CI passed, merging PR..." + break + fi + fi + done + + - name: Merge the PR + env: + GITHUB_TOKEN: ${{ secrets.PAT_SERVICE_ACCOUNT }} + run: | + pr_number=${{ needs.update-submodule.outputs.pr_number }} + gh pr merge $pr_number --merge --admin + + create-tag: + needs: [update-submodule, check-and-merge-pr] + if: needs.update-submodule.outputs.pr_created == 'true' + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + submodules: recursive + ref: dev + fetch-depth: 0 + token: ${{ secrets.PAT_SERVICE_ACCOUNT }} + + - name: Configure Git + run: | + git config --global user.name 'github-actions[bot]' + git config --global user.email 'github-actions[bot]@users.noreply.github.com' + + - name: Create and push a new tag + run: | + # Function to get the latest release tag + get_latest_tag() { + local retries=0 + local max_retries=3 + local tag + while [ $retries -lt $max_retries ]; do + tag=$(curl -s https://api.github.com/repos/janhq/cortex/releases/latest | jq -r .tag_name) + if [ -n "$tag" ] && [ "$tag" != "null" ]; then + echo $tag + return + else + let retries++ + echo "Retrying... ($retries/$max_retries)" + sleep 2 + fi + done + echo "Failed to fetch latest tag after $max_retries attempts." + exit 1 + } + + LATEST_TAG=$(get_latest_tag) + date_suffix=$(date +'%d.%m.%y') + new_tag="${LATEST_TAG}-${date_suffix}" + git tag $new_tag + git push origin $new_tag