1- name : PR New Environment
1+ name : PR New Environment
2+
3+ on :
4+ pull_request_target :
5+ types :
6+ - opened
7+ - reopened
8+ - synchronize
9+ paths :
10+ - ' src/envs/**'
11+
12+ permissions :
13+ contents : read
14+ pull-requests : read
15+
16+ jobs :
17+ detect-new-envs :
18+ name : Detect Newly Added Environments
19+ runs-on : ubuntu-latest
20+ outputs :
21+ has_new_envs : ${{ steps.detect.outputs.has_new_envs }}
22+ new_envs : ${{ steps.detect.outputs.new_envs }}
23+ new_envs_json : ${{ steps.detect.outputs.new_envs_json }}
24+ steps :
25+ - name : Checkout base branch
26+ uses : actions/checkout@v4
27+ with :
28+ ref : ${{ github.event.pull_request.base.ref }}
29+ path : base
30+ fetch-depth : 0
31+ persist-credentials : false
32+
33+ - name : Checkout PR branch
34+ uses : actions/checkout@v4
35+ with :
36+ repository : ${{ github.event.pull_request.head.repo.full_name }}
37+ ref : ${{ github.event.pull_request.head.ref }}
38+ path : pr
39+ fetch-depth : 0
40+ persist-credentials : false
41+
42+ - name : Determine new environment directories
43+ id : detect
44+ shell : bash
45+ run : |
46+ set -euo pipefail
47+
48+ if [ ! -d base/src/envs ]; then
49+ echo "Base repository missing src/envs directory."
50+ echo "has_new_envs=false" >> "$GITHUB_OUTPUT"
51+ echo "new_envs=" >> "$GITHUB_OUTPUT"
52+ echo "new_envs_json=[]" >> "$GITHUB_OUTPUT"
53+ exit 0
54+ fi
55+
56+ if [ ! -d pr/src/envs ]; then
57+ echo "PR repository missing src/envs directory."
58+ echo "has_new_envs=false" >> "$GITHUB_OUTPUT"
59+ echo "new_envs=" >> "$GITHUB_OUTPUT"
60+ echo "new_envs_json=[]" >> "$GITHUB_OUTPUT"
61+ exit 0
62+ fi
63+
64+ mapfile -t BASE_ENVS < <(cd base/src/envs && find . -maxdepth 1 -mindepth 1 -type d | sed 's|^\./||' | sort)
65+ mapfile -t PR_ENVS < <(cd pr/src/envs && find . -maxdepth 1 -mindepth 1 -type d | sed 's|^\./||' | sort)
66+
67+ declare -A BASE_SET=()
68+ for env in "${BASE_ENVS[@]}"; do
69+ BASE_SET["$env"]=1
70+ done
71+
72+ NEW_ENV_ARRAY=()
73+ for env in "${PR_ENVS[@]}"; do
74+ if [ -z "${BASE_SET[$env]:-}" ]; then
75+ NEW_ENV_ARRAY+=("$env")
76+ fi
77+ done
78+
79+ if [ ${#NEW_ENV_ARRAY[@]} -eq 0 ]; then
80+ echo "No new environment directories detected."
81+ echo "has_new_envs=false" >> "$GITHUB_OUTPUT"
82+ echo "new_envs=" >> "$GITHUB_OUTPUT"
83+ echo "new_envs_json=[]" >> "$GITHUB_OUTPUT"
84+ exit 0
85+ fi
86+
87+ printf 'Detected new environments: %s\n' "$(printf '%s ' "${NEW_ENV_ARRAY[@]}")"
88+
89+ NEW_ENVS_COMMA=$(printf '%s\n' "${NEW_ENV_ARRAY[@]}" | paste -sd, -)
90+ NEW_ENVS_JSON=$(printf '%s\n' "${NEW_ENV_ARRAY[@]}" | python -c 'import json,sys; print(json.dumps([line.strip() for line in sys.stdin if line.strip()]))')
91+
92+ echo "has_new_envs=true" >> "$GITHUB_OUTPUT"
93+ echo "new_envs=${NEW_ENVS_COMMA}" >> "$GITHUB_OUTPUT"
94+ echo "new_envs_json=${NEW_ENVS_JSON}" >> "$GITHUB_OUTPUT"
95+
96+ deploy-and-health-check :
97+ name : Deploy and Validate New Environments
98+ needs : detect-new-envs
99+ if : needs.detect-new-envs.outputs.has_new_envs == 'true'
100+ runs-on : ubuntu-latest
101+ strategy :
102+ matrix :
103+ environment : ${{ fromJSON(needs.detect-new-envs.outputs.new_envs_json) }}
104+ env :
105+ HF_TOKEN : ${{ secrets.HF_PR_TOKEN }}
106+ HF_NAMESPACE : ${{ vars.HF_PR_NAMESPACE }}
107+ SPACE_SUFFIX : -pr-${{ github.event.number }}
108+ steps :
109+ - name : Checkout PR code
110+ uses : actions/checkout@v4
111+ with :
112+ repository : ${{ github.event.pull_request.head.repo.full_name }}
113+ ref : ${{ github.event.pull_request.head.ref }}
114+ fetch-depth : 0
115+ persist-credentials : false
116+
117+ - name : Default Hugging Face namespace
118+ if : env.HF_NAMESPACE == ''
119+ shell : bash
120+ run : echo "HF_NAMESPACE=openenv-testing" >> "$GITHUB_ENV"
121+
122+ - name : Verify Hugging Face token
123+ shell : bash
124+ run : |
125+ if [ -z "${HF_TOKEN:-}" ]; then
126+ echo "HF_TOKEN secret is required for deployment." >&2
127+ exit 1
128+ fi
129+
130+ - name : Install Hugging Face CLI
131+ shell : bash
132+ run : |
133+ curl -LsSf https://hf.co/cli/install.sh | bash
134+ echo "$HOME/.local/bin" >> "$GITHUB_PATH"
135+
136+ - name : Deploy environment to Hugging Face
137+ shell : bash
138+ run : |
139+ set -euo pipefail
140+ chmod +x scripts/deploy_to_hf.sh
141+ ./scripts/deploy_to_hf.sh --env "${{ matrix.environment }}" --space-suffix "${SPACE_SUFFIX}" --private
142+
143+ - name : Wait for deployment to stabilize
144+ shell : bash
145+ run : sleep 300
146+
147+ - name : Perform environment health check
148+ shell : bash
149+ run : |
150+ set -euo pipefail
151+
152+ if [ -z "${HF_NAMESPACE:-}" ]; then
153+ echo "HF_NAMESPACE is not configured; unable to compute health check URL." >&2
154+ exit 1
155+ fi
156+
157+ namespace_slug=$(echo "${HF_NAMESPACE}" | tr '[:upper:]' '[:lower:]' | tr '_' '-')
158+ space_name="${{ matrix.environment }}${SPACE_SUFFIX}"
159+ space_slug=$(echo "${space_name}" | tr '[:upper:]' '[:lower:]' | tr '_' '-')
160+ health_url="https://${namespace_slug}-${space_slug}.hf.space/health"
161+
162+ echo "Checking health for ${space_name} at ${health_url}"
163+
164+ success=0
165+ for attempt in {1..5}; do
166+ status=$(curl -sS -o response.json -w "%{http_code}" "$health_url" || echo "000")
167+ if [ "$status" = "200" ]; then
168+ echo "Health check passed for ${space_name}"
169+ cat response.json
170+ success=1
171+ break
172+ fi
173+ echo "Attempt ${attempt} returned status ${status}. Retrying in 30 seconds..."
174+ sleep 30
175+ done
176+
177+ if [ $success -ne 1 ]; then
178+ echo "Health check failed for ${space_name}" >&2
179+ if [ -f response.json ]; then
180+ echo "Last response payload:"
181+ cat response.json
182+ fi
183+ exit 1
184+ fi
185+
186+ >>>>>>> gh-action-deploy-test
0 commit comments