1+ name : Production Build Notification
2+
3+ on :
4+ push :
5+ branches :
6+ - main
7+
8+ jobs :
9+ notify-prod-build :
10+ runs-on : ubuntu-latest
11+ steps :
12+ - name : Checkout
13+ uses : actions/checkout@v4
14+
15+ - name : Find merged PR
16+ id : find-pr
17+ uses : actions/github-script@v7
18+ with :
19+ script : |
20+ // Get the commit that triggered this push
21+ const commit = context.sha;
22+
23+ // Find PRs that were merged with this commit
24+ const prs = await github.rest.repos.listPullRequestsAssociatedWithCommit({
25+ owner: context.repo.owner,
26+ repo: context.repo.repo,
27+ commit_sha: commit
28+ });
29+
30+ // Find the merged PR
31+ const mergedPR = prs.data.find(pr => pr.merged_at && pr.base.ref === 'main');
32+
33+ if (mergedPR) {
34+ console.log(`Found merged PR: #${mergedPR.number}`);
35+ return {
36+ number: mergedPR.number,
37+ title: mergedPR.title,
38+ author: mergedPR.user.login,
39+ url: mergedPR.html_url
40+ };
41+ } else {
42+ console.log('No merged PR found for this commit');
43+ return null;
44+ }
45+
46+ - name : Wait for Netlify deployment
47+ run : sleep 90
48+
49+ - name : Check Netlify deployment status
50+ id : netlify-status
51+ run : |
52+ # Get latest deployment from Netlify API
53+ DEPLOY_DATA=$(curl -s -H "Authorization: Bearer ${{ secrets.NETLIFY_TOKEN }}" \
54+ "https://api.netlify.com/api/v1/sites/cockroachdb-docs/deploys?per_page=1")
55+
56+ DEPLOY_STATE=$(echo "$DEPLOY_DATA" | jq -r '.[0].state')
57+ DEPLOY_URL=$(echo "$DEPLOY_DATA" | jq -r '.[0].deploy_ssl_url')
58+ COMMIT_SHA=$(echo "$DEPLOY_DATA" | jq -r '.[0].commit_ref')
59+ DEPLOY_ID=$(echo "$DEPLOY_DATA" | jq -r '.[0].id')
60+
61+ echo "deploy_state=$DEPLOY_STATE" >> $GITHUB_OUTPUT
62+ echo "deploy_url=$DEPLOY_URL" >> $GITHUB_OUTPUT
63+ echo "commit_sha=$COMMIT_SHA" >> $GITHUB_OUTPUT
64+ echo "deploy_id=$DEPLOY_ID" >> $GITHUB_OUTPUT
65+
66+ echo "Deployment state: $DEPLOY_STATE"
67+ echo "Deployment URL: $DEPLOY_URL"
68+ echo "Commit SHA: $COMMIT_SHA"
69+
70+ - name : Create GitHub deployment
71+ id : deployment
72+ uses : actions/github-script@v7
73+ with :
74+ script : |
75+ const deployment = await github.rest.repos.createDeployment({
76+ owner: context.repo.owner,
77+ repo: context.repo.repo,
78+ ref: context.sha,
79+ environment: 'production',
80+ description: 'Production deployment via Netlify',
81+ auto_merge: false,
82+ required_contexts: []
83+ });
84+ return deployment.data.id;
85+
86+ - name : Update GitHub deployment status - Success
87+ if : steps.netlify-status.outputs.deploy_state == 'ready'
88+ uses : actions/github-script@v7
89+ with :
90+ script : |
91+ await github.rest.repos.createDeploymentStatus({
92+ owner: context.repo.owner,
93+ repo: context.repo.repo,
94+ deployment_id: ${{ steps.deployment.outputs.result }},
95+ state: 'success',
96+ environment: 'production',
97+ environment_url: 'https://www.cockroachlabs.com',
98+ description: 'Production deployment successful'
99+ });
100+
101+ - name : Update GitHub deployment status - Failure
102+ if : steps.netlify-status.outputs.deploy_state == 'error'
103+ uses : actions/github-script@v7
104+ with :
105+ script : |
106+ await github.rest.repos.createDeploymentStatus({
107+ owner: context.repo.owner,
108+ repo: context.repo.repo,
109+ deployment_id: ${{ steps.deployment.outputs.result }},
110+ state: 'failure',
111+ environment: 'production',
112+ description: 'Production deployment failed'
113+ });
114+
115+ - name : Send Slack notification - Success
116+ if : steps.netlify-status.outputs.deploy_state == 'ready'
117+ run : |
118+ echo "🔔 Sending production success notification to Slack..."
119+ RESPONSE=$(curl -X POST -H 'Content-type: application/json' \
120+ --data "{
121+ \"text\": \"✅ Production build successful!\",
122+ \"blocks\": [
123+ {
124+ \"type\": \"section\",
125+ \"text\": {
126+ \"type\": \"mrkdwn\",
127+ \"text\": \"*Production Build Successful* ✅\\n\\n*Site:* <https://www.cockroachlabs.com|cockroachlabs.com>\\n*Commit:* \\\`${{ steps.netlify-status.outputs.commit_sha }}\\\`\\n*Branch:* main\\n*Deploy ID:* ${{ steps.netlify-status.outputs.deploy_id }}\"
128+ }
129+ }
130+ ]
131+ }" \
132+ --write-out "%{http_code}" \
133+ --silent \
134+ --output /tmp/slack_response.txt \
135+ ${{ secrets.SLACK_WEBHOOK_URL }})
136+
137+ echo "Slack response code: $RESPONSE"
138+ if [ "$RESPONSE" = "200" ]; then
139+ echo "✅ Slack notification sent successfully"
140+ else
141+ echo "❌ Slack notification failed with code: $RESPONSE"
142+ echo "Response body:"
143+ cat /tmp/slack_response.txt
144+ fi
145+
146+ - name : Comment on PR - Success
147+ if : steps.netlify-status.outputs.deploy_state == 'ready' && fromJSON(steps.find-pr.outputs.result) != null
148+ uses : actions/github-script@v7
149+ with :
150+ script : |
151+ const prInfo = ${{ steps.find-pr.outputs.result }};
152+ if (prInfo) {
153+ const commentBody = `## 🚀 Production Deployment Successful!
154+
155+ **✅ Your changes are now live on [cockroachlabs.com](https://www.cockroachlabs.com)**
156+
157+ **Deployment Details:**
158+ - **PR:** #${prInfo.number} - ${prInfo.title}
159+ - **Author:** @${prInfo.author}
160+ - **Commit:** \`${{ steps.netlify-status.outputs.commit_sha }}\`
161+ - **Deploy ID:** ${{ steps.netlify-status.outputs.deploy_id }}
162+ - **Deploy URL:** ${{ steps.netlify-status.outputs.deploy_url }}
163+
164+ *Deployment completed successfully! 🎉*`;
165+
166+ await github.rest.issues.createComment({
167+ issue_number: prInfo.number,
168+ owner: context.repo.owner,
169+ repo: context.repo.repo,
170+ body: commentBody
171+ });
172+ }
173+
174+ - name : Send Slack notification - Failure
175+ if : steps.netlify-status.outputs.deploy_state == 'error'
176+ run : |
177+ echo "🔔 Sending production failure notification to Slack..."
178+ RESPONSE=$(curl -X POST -H 'Content-type: application/json' \
179+ --data "{
180+ \"text\": \"❌ Production build failed!\",
181+ \"blocks\": [
182+ {
183+ \"type\": \"section\",
184+ \"text\": {
185+ \"type\": \"mrkdwn\",
186+ \"text\": \"*Production Build Failed* ❌\\n\\n*Commit:* \\\`${{ steps.netlify-status.outputs.commit_sha }}\\\`\\n*Branch:* main\\n*Deploy ID:* ${{ steps.netlify-status.outputs.deploy_id }}\\n*Error:* Check Netlify dashboard for details\"
187+ }
188+ }
189+ ]
190+ }" \
191+ --write-out "%{http_code}" \
192+ --silent \
193+ --output /tmp/slack_response.txt \
194+ ${{ secrets.SLACK_WEBHOOK_URL }})
195+
196+ echo "Slack response code: $RESPONSE"
197+ if [ "$RESPONSE" = "200" ]; then
198+ echo "✅ Slack notification sent successfully"
199+ else
200+ echo "❌ Slack notification failed with code: $RESPONSE"
201+ echo "Response body:"
202+ cat /tmp/slack_response.txt
203+ fi
204+
205+ - name : Comment on PR - Failure
206+ if : steps.netlify-status.outputs.deploy_state == 'error' && fromJSON(steps.find-pr.outputs.result) != null
207+ uses : actions/github-script@v7
208+ with :
209+ script : |
210+ const prInfo = ${{ steps.find-pr.outputs.result }};
211+ if (prInfo) {
212+ const commentBody = `## ❌ Production Deployment Failed
213+
214+ **🚨 There was an issue deploying your changes to production**
215+
216+ **Deployment Details:**
217+ - **PR:** #${prInfo.number} - ${prInfo.title}
218+ - **Author:** @${prInfo.author}
219+ - **Commit:** \`${{ steps.netlify-status.outputs.commit_sha }}\`
220+ - **Deploy ID:** ${{ steps.netlify-status.outputs.deploy_id }}
221+ - **Status:** Failed
222+
223+ **Next Steps:**
224+ - Check the [Netlify dashboard](https://app.netlify.com/sites/cockroachdb-docs/deploys) for error details
225+ - Review build logs for the specific error
226+ - Contact the docs team if you need assistance
227+
228+ *Please investigate and resolve the deployment issue.*`;
229+
230+ await github.rest.issues.createComment({
231+ issue_number: prInfo.number,
232+ owner: context.repo.owner,
233+ repo: context.repo.repo,
234+ body: commentBody
235+ });
236+ }
237+
238+ - name : Handle pending deployment
239+ if : steps.netlify-status.outputs.deploy_state == 'building' || steps.netlify-status.outputs.deploy_state == 'enqueued'
240+ run : |
241+ echo "::warning::Deployment still in progress after 90 seconds: ${{ steps.netlify-status.outputs.deploy_state }}"
242+ echo "🔔 Sending production pending notification to Slack..."
243+ RESPONSE=$(curl -X POST -H 'Content-type: application/json' \
244+ --data "{
245+ \"text\": \"⏳ Production build still in progress...\",
246+ \"blocks\": [
247+ {
248+ \"type\": \"section\",
249+ \"text\": {
250+ \"type\": \"mrkdwn\",
251+ \"text\": \"*Production Build In Progress* ⏳\\n\\n*Status:* ${{ steps.netlify-status.outputs.deploy_state }}\\n*Commit:* \\\`${{ steps.netlify-status.outputs.commit_sha }}\\\`\\n*Branch:* main\\n*Note:* Check Netlify dashboard for completion status\"
252+ }
253+ }
254+ ]
255+ }" \
256+ --write-out "%{http_code}" \
257+ --silent \
258+ --output /tmp/slack_response.txt \
259+ ${{ secrets.SLACK_WEBHOOK_URL }})
260+
261+ echo "Slack response code: $RESPONSE"
262+ if [ "$RESPONSE" = "200" ]; then
263+ echo "✅ Slack notification sent successfully"
264+ else
265+ echo "❌ Slack notification failed with code: $RESPONSE"
266+ echo "Response body:"
267+ cat /tmp/slack_response.txt
268+ fi
269+
270+ - name : Comment on PR - Pending
271+ if : (steps.netlify-status.outputs.deploy_state == 'building' || steps.netlify-status.outputs.deploy_state == 'enqueued') && fromJSON(steps.find-pr.outputs.result) != null
272+ uses : actions/github-script@v7
273+ with :
274+ script : |
275+ const prInfo = ${{ steps.find-pr.outputs.result }};
276+ if (prInfo) {
277+ const commentBody = `## ⏳ Production Deployment In Progress
278+
279+ **🔄 Your changes are currently being deployed to production**
280+
281+ **Deployment Details:**
282+ - **PR:** #${prInfo.number} - ${prInfo.title}
283+ - **Author:** @${prInfo.author}
284+ - **Commit:** \`${{ steps.netlify-status.outputs.commit_sha }}\`
285+ - **Deploy ID:** ${{ steps.netlify-status.outputs.deploy_id }}
286+ - **Status:** ${{ steps.netlify-status.outputs.deploy_state }}
287+
288+ **Note:** Deployment is taking longer than expected (>90 seconds). Please check the [Netlify dashboard](https://app.netlify.com/sites/cockroachdb-docs/deploys) for current status.
289+
290+ *Will update when deployment completes.*`;
291+
292+ await github.rest.issues.createComment({
293+ issue_number: prInfo.number,
294+ owner: context.repo.owner,
295+ repo: context.repo.repo,
296+ body: commentBody
297+ });
298+ }
0 commit comments