From 1173b3bbc56aa03aaff0597a68bc26c19b071118 Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Wed, 16 Jul 2025 22:17:01 +0100 Subject: [PATCH 1/3] Deploy previews --- .github/workflows/deploy-preview.yaml | 217 ++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 .github/workflows/deploy-preview.yaml diff --git a/.github/workflows/deploy-preview.yaml b/.github/workflows/deploy-preview.yaml new file mode 100644 index 000000000..04349be8d --- /dev/null +++ b/.github/workflows/deploy-preview.yaml @@ -0,0 +1,217 @@ +name: "Deploy Preview" + +env: + TEST_USERNAME: "preview-user" + TEST_PASSWORD: "P@sswo3d" + TEST_SUPERADMIN_USER: "preview-admin" + TEST_SUPERADMIN_PASSWORD: "P@sswo3d-admin" + NEBARI_IMAGE_TAG: "main" + PYTHON_VERSION: "3.11" + +on: + pull_request: + types: [labeled, unlabeled] + +concurrency: + group: deploy-preview-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + deploy-preview: + if: github.event.action == 'labeled' && github.event.label.name == 'deploy-preview' + runs-on: "cirun-runner--${{ github.run_id }}" + defaults: + run: + shell: bash -l {0} + env: + APP_DNS: "nebari-pr-${{ github.event.pull_request.number }}.nebari.dev" + SSH_DNS: "nebari-pr-${{ github.event.pull_request.number }}-ssh.nebari.dev" + PREVIEW_DIR: "preview-pr-${{ github.event.pull_request.number }}" + steps: + - name: "Checkout Infrastructure" + uses: actions/checkout@main + with: + fetch-depth: 0 + + - name: "Checkout PR" + run: | + git fetch origin pull/${{ github.event.pull_request.number }}/head:pr-${{ github.event.pull_request.number }} + git checkout pr-${{ github.event.pull_request.number }} + + # https://kind.sigs.k8s.io/docs/user/known-issues/#pod-errors-due-to-too-many-open-files + - name: "Update inotify ulimit" + run: | + sudo sysctl fs.inotify.max_user_watches=524288 + sudo sysctl fs.inotify.max_user_instances=512 + + - name: Setup runner for local deployment + uses: ./.github/actions/setup-local + + - name: Set up Python + uses: conda-incubator/setup-miniconda@v3 + env: + CONDA: /home/runnerx/miniconda3 + with: + auto-update-conda: true + python-version: ${{ env.PYTHON_VERSION }} + miniconda-version: "latest" + activate-environment: nebari + + - name: Install JQ + run: | + sudo apt-get update + sudo apt-get install jq -y + + - name: Install Nebari + run: pip install .[dev] + + - name: Initialize Nebari config for preview deployment + id: init + run: | + mkdir -p ${{ env.PREVIEW_DIR }} + cd ${{ env.PREVIEW_DIR }} + + nebari init local --domain ${{ env.APP_DNS }} --namespace dev --auth-provider password + + echo "domain=${{ env.APP_DNS }}" >> $GITHUB_OUTPUT + echo "directory=${{ env.PREVIEW_DIR }}" >> $GITHUB_OUTPUT + echo "config=nebari-config.yaml" >> $GITHUB_OUTPUT + + - name: Deploy Nebari Preview + working-directory: ${{ steps.init.outputs.directory }} + run: nebari deploy --config ${{ steps.init.outputs.config }} --disable-prompt + + - name: Health check + uses: ./.github/actions/health-check + with: + domain: ${{ steps.init.outputs.domain }} + + - name: Create preview users + working-directory: ${{ steps.init.outputs.directory }} + run: | + nebari keycloak add-user --user "${TEST_USERNAME}" -p "${TEST_PASSWORD}" --config ${{ steps.init.outputs.config }} + nebari keycloak add-user --user "${TEST_SUPERADMIN_USER}" -p "${TEST_SUPERADMIN_PASSWORD}" --config ${{ steps.init.outputs.config }} --groups superadmin + nebari keycloak list-users --config ${{ steps.init.outputs.config }} + + - name: Await Workloads + uses: jupyterhub/action-k8s-await-workloads@v3 + with: + workloads: "" # all + namespace: "dev" + timeout: 300 + max-restarts: 3 + + - name: Setup FRP Tunnel + uses: cirunlabs/frp-tunnel-action@main + with: + timeout_minutes: 0 + frp_client_config: | + serverAddr = "frp.nebari.dev" + serverPort = 7000 + auth.method = "token" + auth.token = "${{ secrets.FRP_TOKEN }}" + + [[proxies]] + name = "nebari-ssh--${{ github.run_id }}-${{ github.sha }}" + type = "tcpmux" + multiplexer = "httpconnect" + localIP = "127.0.0.1" + localPort = 22 + customDomains = ["${{ env.SSH_DNS }}"] + + [[proxies]] + name = "nebari-http--${{ github.run_id }}-${{ github.sha }}" + type = "https" + localIP = "127.0.0.1" + localPort = 443 + customDomains = ["${{ env.APP_DNS }}"] + + - name: Comment on PR with deployment info + uses: actions/github-script@v7 + with: + script: | + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: ${{ github.event.pull_request.number }} + }); + + const existingComment = comments.find(comment => + comment.body.includes('๐Ÿš€ Deploy Preview') && comment.user.login === 'github-actions[bot]' + ); + + const body = `## ๐Ÿš€ Deploy Preview Ready! + + Your Nebari preview deployment is now available: + + **๐ŸŒ Preview URL:** https://${{ env.APP_DNS }} + + **๐Ÿ‘ค Test Credentials:** + - **User:** \`${{ env.TEST_USERNAME }}\` / \`${{ env.TEST_PASSWORD }}\` + - **Admin:** \`${{ env.TEST_SUPERADMIN_USER }}\` / \`${{ env.TEST_SUPERADMIN_PASSWORD }}\` + + **๐Ÿ”— SSH Access:** + \`\`\`bash + ssh ubuntu@${{ env.SSH_DNS }} + \`\`\` + + **๐Ÿ”„ Auto-cleanup:** This preview will be automatically cleaned up when the \`deploy-preview\` label is removed or the runner terminates. + + --- + _This preview was generated from commit ${context.sha.slice(0, 7)}_`; + + if (existingComment) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existingComment.id, + body: body + }); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: ${{ github.event.pull_request.number }}, + body: body + }); + } + + cleanup-preview: + if: github.event.action == 'unlabeled' && github.event.label.name == 'deploy-preview' + runs-on: ubuntu-latest + steps: + - name: Comment on PR about cleanup + uses: actions/github-script@v7 + with: + script: | + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: ${{ github.event.pull_request.number }} + }); + + const existingComment = comments.find(comment => + comment.body.includes('๐Ÿš€ Deploy Preview') && comment.user.login === 'github-actions[bot]' + ); + + const body = `## ๐Ÿงน Deploy Preview Cleaned Up + + The preview deployment for PR #${{ github.event.pull_request.number }} has been cleaned up. + + To create a new preview, add the \`deploy-preview\` label again.`; + + if (existingComment) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existingComment.id, + body: body + }); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: ${{ github.event.pull_request.number }}, + body: body + }); + } \ No newline at end of file From be810555c9967280312bf5bd4269e9a5e83ca493 Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Wed, 16 Jul 2025 22:51:49 +0100 Subject: [PATCH 2/3] fix init params --- .github/workflows/deploy-preview.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy-preview.yaml b/.github/workflows/deploy-preview.yaml index 04349be8d..a2ff2ccdc 100644 --- a/.github/workflows/deploy-preview.yaml +++ b/.github/workflows/deploy-preview.yaml @@ -71,7 +71,11 @@ jobs: mkdir -p ${{ env.PREVIEW_DIR }} cd ${{ env.PREVIEW_DIR }} - nebari init local --domain ${{ env.APP_DNS }} --namespace dev --auth-provider password + nebari init local \ + --project-name 'preview-pr-${{ github.event.pull_request.number }}' \ + --domain-name '${{ env.APP_DNS }}' \ + --auth-provider password \ + --output 'nebari-config.yaml' echo "domain=${{ env.APP_DNS }}" >> $GITHUB_OUTPUT echo "directory=${{ env.PREVIEW_DIR }}" >> $GITHUB_OUTPUT From da1402e2012052cd81edf7fa0c15dcdfc3e362a2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 16 Jul 2025 21:52:05 +0000 Subject: [PATCH 3/3] [pre-commit.ci] Apply automatic pre-commit fixes --- .github/workflows/deploy-preview.yaml | 38 +++++++++++++-------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/workflows/deploy-preview.yaml b/.github/workflows/deploy-preview.yaml index a2ff2ccdc..030141cd8 100644 --- a/.github/workflows/deploy-preview.yaml +++ b/.github/workflows/deploy-preview.yaml @@ -70,13 +70,13 @@ jobs: run: | mkdir -p ${{ env.PREVIEW_DIR }} cd ${{ env.PREVIEW_DIR }} - + nebari init local \ --project-name 'preview-pr-${{ github.event.pull_request.number }}' \ --domain-name '${{ env.APP_DNS }}' \ --auth-provider password \ --output 'nebari-config.yaml' - + echo "domain=${{ env.APP_DNS }}" >> $GITHUB_OUTPUT echo "directory=${{ env.PREVIEW_DIR }}" >> $GITHUB_OUTPUT echo "config=nebari-config.yaml" >> $GITHUB_OUTPUT @@ -139,31 +139,31 @@ jobs: repo: context.repo.repo, issue_number: ${{ github.event.pull_request.number }} }); - - const existingComment = comments.find(comment => + + const existingComment = comments.find(comment => comment.body.includes('๐Ÿš€ Deploy Preview') && comment.user.login === 'github-actions[bot]' ); - + const body = `## ๐Ÿš€ Deploy Preview Ready! - + Your Nebari preview deployment is now available: - + **๐ŸŒ Preview URL:** https://${{ env.APP_DNS }} - + **๐Ÿ‘ค Test Credentials:** - **User:** \`${{ env.TEST_USERNAME }}\` / \`${{ env.TEST_PASSWORD }}\` - **Admin:** \`${{ env.TEST_SUPERADMIN_USER }}\` / \`${{ env.TEST_SUPERADMIN_PASSWORD }}\` - + **๐Ÿ”— SSH Access:** \`\`\`bash ssh ubuntu@${{ env.SSH_DNS }} \`\`\` - + **๐Ÿ”„ Auto-cleanup:** This preview will be automatically cleaned up when the \`deploy-preview\` label is removed or the runner terminates. - + --- _This preview was generated from commit ${context.sha.slice(0, 7)}_`; - + if (existingComment) { await github.rest.issues.updateComment({ owner: context.repo.owner, @@ -193,17 +193,17 @@ jobs: repo: context.repo.repo, issue_number: ${{ github.event.pull_request.number }} }); - - const existingComment = comments.find(comment => + + const existingComment = comments.find(comment => comment.body.includes('๐Ÿš€ Deploy Preview') && comment.user.login === 'github-actions[bot]' ); - + const body = `## ๐Ÿงน Deploy Preview Cleaned Up - + The preview deployment for PR #${{ github.event.pull_request.number }} has been cleaned up. - + To create a new preview, add the \`deploy-preview\` label again.`; - + if (existingComment) { await github.rest.issues.updateComment({ owner: context.repo.owner, @@ -218,4 +218,4 @@ jobs: issue_number: ${{ github.event.pull_request.number }}, body: body }); - } \ No newline at end of file + }