forked from github/docs
-
Notifications
You must be signed in to change notification settings - Fork 0
199 lines (170 loc) · 6.9 KB
/
prod-build-deploy.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
name: Production - Build and Deploy
# **What it does**: Builds and deploys the default branch to production
# **Why we have it**: To enable us to deploy the latest to production whenever necessary rather than relying on PR merges.
# **Who does it impact**: All contributors.
on:
push:
branches:
- main
workflow_dispatch:
permissions:
contents: read
deployments: write
# This allows a subsequently queued workflow run to take priority over
# previously queued runs but NOT interrupt currently executing runs
concurrency:
group: '${{ github.workflow }}'
cancel-in-progress: false
jobs:
build-and-deploy:
if: ${{ github.repository == 'github/docs-internal'}}
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Check out repo
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
with:
persist-credentials: 'false'
lfs: 'true'
- name: Check out LFS objects
run: git lfs checkout
- name: Setup node
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
with:
node-version: 16.13.x
cache: npm
# Required for `npm pkg ...` command support
- name: Update to npm@^7.20.0
run: npm install --global npm@^7.20.0
- name: Install dependencies
run: npm ci
- name: Clone early access
run: node script/early-access/clone-for-build.js
env:
DOCUBOT_REPO_PAT: ${{ secrets.DOCUBOT_REPO_PAT }}
GIT_BRANCH: main
- name: Cache nextjs build
uses: actions/cache@937d24475381cd9c75ae6db12cb4e79714b926ed
with:
path: .next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('package*.json') }}
- name: Build
run: npm run build
- name: Remove development-only dependencies
run: npm prune --production
- name: Remove all npm scripts
run: npm pkg delete scripts
- name: Set npm script for Heroku build to noop
run: npm set-script heroku-postbuild "echo 'Application was pre-built!'"
- name: Create a gzipped archive
run: |
tar -cz --file=app.tar.gz \
node_modules/ \
.next/ \
assets/ \
content/ \
data/ \
includes/ \
lib/ \
middleware/ \
translations/ \
server.mjs \
package*.json \
.npmrc \
feature-flags.json \
next.config.js \
app.json \
Procfile
- name: Install the development dependencies again
run: npm install
- name: Create a Heroku build source
id: build-source
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
env:
HEROKU_API_TOKEN: ${{ secrets.HEROKU_API_TOKEN }}
with:
script: |
const { owner, repo } = context.repo
if (owner !== 'github') {
throw new Error(`Repository owner must be 'github' but was: ${owner}`)
}
if (repo !== 'docs-internal') {
throw new Error(`Repository name must be 'docs-internal' but was: ${repo}`)
}
const Heroku = require('heroku-client')
const heroku = new Heroku({ token: process.env.HEROKU_API_TOKEN })
try {
const { source_blob: sourceBlob } = await heroku.post('/sources')
const { put_url: uploadUrl, get_url: downloadUrl } = sourceBlob
core.setOutput('upload_url', uploadUrl)
core.setOutput('download_url', downloadUrl)
} catch (error) {
if (error.statusCode === 503) {
console.error('💀 Heroku may be down! Please check its Status page: https://status.heroku.com/')
}
throw error
}
# See: https://devcenter.heroku.com/articles/build-and-release-using-the-api#sources-endpoint
- name: Upload to the Heroku build source
env:
UPLOAD_URL: ${{ steps.build-source.outputs.upload_url }}
run: |
curl "$UPLOAD_URL" \
-X PUT \
-H 'Content-Type:' \
--data-binary @app.tar.gz
- name: Deploy
id: deploy
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HEROKU_API_TOKEN: ${{ secrets.HEROKU_API_TOKEN }}
HEROKU_PRODUCTION_APP_NAME: ${{ secrets.HEROKU_PRODUCTION_APP_NAME }}
HYDRO_ENDPOINT: ${{ secrets.HYDRO_ENDPOINT }}
HYDRO_SECRET: ${{ secrets.HYDRO_SECRET }}
SOURCE_BLOB_URL: ${{ steps.build-source.outputs.download_url }}
DELAY_FOR_PREBOOT: 'true'
ALLOWED_POLLING_FAILURES_PER_PHASE: '15'
RUN_ID: ${{ github.run_id }}
run: .github/actions-scripts/prod-deploy.js
- name: Mark the deployment as inactive if timed out
uses: actions/github-script@2b34a689ec86a68d8ab9478298f91d5401337b7d
if: ${{ steps.deploy.outcome == 'cancelled' }}
env:
DEPLOYMENT_ID: ${{ steps.deploy.outputs.deploymentId }}
LOG_URL: ${{ steps.deploy.outputs.logUrl }}
with:
script: |
const { DEPLOYMENT_ID, LOG_URL } = process.env
const { owner, repo } = context.repo
if (!DEPLOYMENT_ID) {
throw new Error('A deployment wasn't created before a timeout occurred!')
}
await github.repos.createDeploymentStatus({
owner,
repo,
deployment_id: DEPLOYMENT_ID,
state: 'error',
description: 'The deployment step timed out. See workflow logs.',
log_url: LOG_URL,
// The 'ant-man' preview is required for `state` values of 'inactive', as well as
// the use of the `log_url`, `environment_url`, and `auto_inactive` parameters.
// The 'flash' preview is required for `state` values of 'in_progress' and 'queued'.
mediaType: {
previews: ['ant-man', 'flash'],
},
})
console.log('⏲️ Deployment status: error - The deployment timed out...')
- name: Purge Fastly edge cache
env:
FASTLY_TOKEN: ${{ secrets.FASTLY_TOKEN }}
FASTLY_SERVICE_ID: ${{ secrets.FASTLY_SERVICE_ID }}
FASTLY_SURROGATE_KEY: 'every-deployment'
run: .github/actions-scripts/purge-fastly-edge-cache.js
- name: Send Slack notification if workflow failed
uses: someimportantcompany/github-actions-slack-message@f8d28715e7b8a4717047d23f48c39827cacad340
if: ${{ failure() }}
with:
channel: ${{ secrets.DOCS_ALERTS_SLACK_CHANNEL_ID }}
bot-token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }}
color: failure
text: Production deployment failed at commit ${{ github.sha }}. See https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}