From 7cf44a6edee171766a8c847137a70706b62d3e1f Mon Sep 17 00:00:00 2001 From: burtenshaw Date: Tue, 4 Nov 2025 10:03:49 +0100 Subject: [PATCH] add cli to to ci for pr --- .github/workflows/pr-new-env.yml | 133 +++++++++++++++++++++++++------ 1 file changed, 108 insertions(+), 25 deletions(-) diff --git a/.github/workflows/pr-new-env.yml b/.github/workflows/pr-new-env.yml index 1374abf7..e7c49c53 100644 --- a/.github/workflows/pr-new-env.yml +++ b/.github/workflows/pr-new-env.yml @@ -103,6 +103,7 @@ jobs: environment: ${{ fromJSON(needs.detect-new-envs.outputs.new_envs_json) }} env: HF_TOKEN: ${{ secrets.HF_PR_TOKEN }} + HF_PR_TOKEN: ${{ secrets.HF_PR_TOKEN }} HF_NAMESPACE: ${{ vars.HF_PR_NAMESPACE }} SPACE_SUFFIX: -pr-${{ github.event.number }} steps: @@ -127,18 +128,31 @@ jobs: exit 1 fi - - name: Install Hugging Face CLI + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install OpenEnv package shell: bash run: | - curl -LsSf https://hf.co/cli/install.sh | bash - echo "$HOME/.local/bin" >> "$GITHUB_PATH" + set -euo pipefail + python -m pip install --upgrade pip + pip install . - - name: Deploy environment to Hugging Face + - name: Deploy environment with OpenEnv CLI shell: bash run: | set -euo pipefail - chmod +x scripts/deploy_to_hf.sh - ./scripts/deploy_to_hf.sh --env "${{ matrix.environment }}" --space-suffix "${SPACE_SUFFIX}" --hub-tag "openenv-pr" + repo_id="${HF_NAMESPACE}/${{ matrix.environment }}${SPACE_SUFFIX}" + env_dir="src/envs/${{ matrix.environment }}" + + if [ ! -d "$env_dir" ]; then + echo "Environment directory not found: $env_dir" >&2 + exit 1 + fi + + openenv push --directory "$env_dir" --repo-id "$repo_id" - name: Wait for deployment to stabilize shell: bash @@ -161,6 +175,7 @@ jobs: health_url="https://${namespace_slug}-${space_slug}.hf.space/health" live_url="https://${namespace_slug}-${space_slug}.hf.space" space_repo_url="https://huggingface.co/spaces/${HF_NAMESPACE}/${space_name}" + space_repo_id="${HF_NAMESPACE}/${space_name}" echo "namespace_slug=${namespace_slug}" >> "$GITHUB_OUTPUT" echo "space_name=${space_name}" >> "$GITHUB_OUTPUT" @@ -168,6 +183,7 @@ jobs: echo "health_url=${health_url}" >> "$GITHUB_OUTPUT" echo "live_url=${live_url}" >> "$GITHUB_OUTPUT" echo "space_repo_url=${space_repo_url}" >> "$GITHUB_OUTPUT" + echo "space_repo_id=${space_repo_id}" >> "$GITHUB_OUTPUT" - name: Perform environment health check id: health_check @@ -216,41 +232,108 @@ jobs: SPACE_NAME: ${{ steps.urls.outputs.space_name }} LIVE_URL: ${{ steps.urls.outputs.live_url }} SPACE_REPO_URL: ${{ steps.urls.outputs.space_repo_url }} + SPACE_REPO_ID: ${{ steps.urls.outputs.space_repo_id }} ENV_NAME: ${{ matrix.environment }} + COMMENT_TAG: "" with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const status = process.env.HEALTH_CONCLUSION || 'failure'; - const spaceName = process.env.SPACE_NAME; - const liveUrl = process.env.LIVE_URL; - const repoUrl = process.env.SPACE_REPO_URL; const envName = process.env.ENV_NAME; + const marker = process.env.COMMENT_TAG; const header = status === 'success' - ? `✅ Deployment succeeded for \`${envName}\`` - : `⚠️ Deployment failed for \`${envName}\``; + ? `✅ Deployment to Hugging Face succeeded for \`${envName}\`` + : `⚠️ Deployment Hugging Face failed for \`${envName}\``; const summary = status === 'success' - ? 'Nice work! Wait for a code review and we\'re ready to go.' - : 'Please resolve your environment.'; + ? 'Nice work! Wait for a code review and we\'re ready to go. You can test it with the CLI:' + : 'Please resolve your environment and test it with the CLI:'; + + const envDir = 'src/envs/' + envName; - const body = [ + const bodyLines = [ + marker, + '', header, '', - `- Space repo: [${repoUrl}](${repoUrl})`, - `- Live URL: [${liveUrl}](${liveUrl})`, '', summary, '', - 'You can iterate locally or validate fixes by running `scripts/deploy_to_hf.sh --env "' + envName + '"`.' - ].join('\n'); - - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.payload.pull_request.number, - body - }); + '- `openenv push --directory ' + envDir + ' --repo-id /' + envName + '`', + ]; + + const {owner, repo} = context.repo; + const issue_number = context.payload.pull_request.number; + const serverUrl = process.env.GITHUB_SERVER_URL || 'https://github.com'; + const runUrl = `${serverUrl}/${owner}/${repo}/actions/runs/${context.runId}`; + + if (status !== 'success') { + bodyLines.push(`- Failed run: ${runUrl}`); + } else { + bodyLines.push(`- Success run: ${runUrl}`); + } + + const bodyText = bodyLines.join('\n'); + + const existing = await github.paginate( + github.rest.issues.listComments, + { owner, repo, issue_number, per_page: 100 }, + (response, done) => { + const match = response.data.find(comment => comment.body && comment.body.includes(marker)); + if (match) { + done(); + return [match]; + } + return []; + } + ); + + if (existing.length > 0) { + await github.rest.issues.updateComment({ + owner, + repo, + comment_id: existing[0].id, + body: bodyText, + }); + } else { + await github.rest.issues.createComment({ + owner, + repo, + issue_number, + body: bodyText, + }); + } + + - name: Delete preview space on Hugging Face + if: always() + continue-on-error: true + shell: bash + env: + SPACE_REPO_ID: ${{ steps.urls.outputs.space_repo_id }} + run: | + set -euo pipefail + if [ -z "${SPACE_REPO_ID:-}" ]; then + echo "No space repo id; skipping deletion" + exit 0 + fi + + TOKEN="${HF_TOKEN:-${HF_PR_TOKEN:-}}" + if [ -z "$TOKEN" ]; then + echo "HF token not available; cannot delete space" + exit 0 + fi + + set +e + hf repo delete "$SPACE_REPO_ID" --repo-type space --yes --token "$TOKEN" + status=$? + set -e + + if [ $status -eq 0 ]; then + echo "Deleted preview space $SPACE_REPO_ID" + else + echo "Failed to delete space $SPACE_REPO_ID (exit $status)" + fi - name: Fail job if health check failed if: steps.health_check.conclusion == 'failure'