Skip to content

Commit 7d60b36

Browse files
committed
Update staging/prod building procedures (#49)
1 parent bc924c0 commit 7d60b36

File tree

1 file changed

+127
-70
lines changed

1 file changed

+127
-70
lines changed

.github/workflows/nginx.org-make-aws.yml

Lines changed: 127 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ on:
55
secrets:
66
AWS_ACCOUNT_ID:
77
required: true
8-
AWS_ROLE_NAME_PROD:
9-
required: true
10-
AWS_ROLE_NAME_STAGING:
8+
AWS_ROLE_NAME:
119
required: true
1210
ALLOWED_USERS:
1311
required: true
@@ -19,12 +17,20 @@ on:
1917
url_prod:
2018
required: false
2119
type: string
22-
default: nginx.org/preview
20+
default: nginx.org
2321
url_staging:
2422
required: false
2523
type: string
26-
default: nginx.org/previews
27-
24+
default: staging.nginx.org
25+
s3_bucket:
26+
required: false
27+
type: string
28+
default: nginx-org-staging
29+
aws_region:
30+
required: false
31+
type: string
32+
default: eu-central-1
33+
2834
permissions:
2935
contents: read
3036
id-token: write
@@ -34,13 +40,54 @@ defaults:
3440
shell: 'bash -Eeo pipefail -x {0}'
3541

3642
jobs:
37-
build:
38-
name: build
43+
check-if-allowed:
44+
if: ${{ ( github.repository_owner == 'nginx' || github.repository_owner == 'nginxinc' ) }}
3945
runs-on: ubuntu-latest
40-
env:
41-
AWS_REGION: eu-central-1
4246

4347
steps:
48+
- name: Check if we're in the allowed environment
49+
run: |
50+
org_found=0
51+
event_found=0
52+
ref_found=0
53+
user_found=0
54+
ALLOWED_ORGS="nginx nginxinc"
55+
ALLOWED_EVENTS="push workflow_dispatch"
56+
ALLOWED_REFS="refs/heads/main"
57+
ALLOWED_USERS="${{ secrets.ALLOWED_USERS }}"
58+
for org in $ALLOWED_ORGS; do
59+
if [ "$org" == "$GITHUB_REPOSITORY_OWNER" ]; then org_found=1; fi
60+
done
61+
for event in $ALLOWED_EVENTS; do
62+
if [ "$event" == "$GITHUB_EVENT_NAME" ]; then event_found=1; fi
63+
done
64+
for ref in $ALLOWED_REFS; do
65+
if [ ${{ inputs.deployment_env }} == 'prod' ]; then
66+
if [ "$ref" == "$GITHUB_REF" ]; then ref_found=1; fi
67+
else
68+
ref_found=1
69+
fi
70+
done
71+
for user in $ALLOWED_USERS; do
72+
if [ ${{ inputs.deployment_env }} == 'prod' ]; then
73+
if [ "$user" == "$GITHUB_ACTOR" ]; then user_found=1; fi
74+
else
75+
user_found=1
76+
fi
77+
done
78+
if [ $org_found$event_found$ref_found$user_found -ne 1111 ]; then
79+
echo "Repository owner, event, ref or actor are not explicitely allowed to use this workflow: $GITHUB_REPOSITORY_OWNER, $GITHUB_EVENT_NAME, $GITHUB_REF, $GITHUB_ACTOR"
80+
exit 1
81+
fi
82+
exit 0
83+
84+
build-staging:
85+
name: build-staging
86+
runs-on: ubuntu-latest
87+
needs: check-if-allowed
88+
if: ${{ inputs.deployment_env == 'staging' }}
89+
90+
steps:
4491
- name: Install dependencies
4592
run: |
4693
sudo apt-get update
@@ -49,56 +96,14 @@ jobs:
4996
- name: Checkout
5097
uses: actions/checkout@v4
5198

52-
- name: Check prod access
53-
if: ${{ inputs.deployment_env == 'prod' }}
54-
run: |
55-
if [ "$GITHUB_REF" != "refs/heads/main" ]; then
56-
echo "Error: Production deployments are only allowed from the main branch."
57-
exit 1
58-
fi
59-
60-
if [ "$GITHUB_REPOSITORY_OWNER" != "nginx" ] && [ "$GITHUB_REPOSITORY_OWNER" != "nginxinc" ]; then
61-
echo "Error: This workflow is only allowed in repositories owned by 'nginx' or 'nginxinc'."
62-
exit 1
63-
fi
64-
65-
ALLOWED="${{ secrets.ALLOWED_USERS }}"
66-
for user in $ALLOWED; do
67-
if [ "$GITHUB_ACTOR" == "$user" ]; then
68-
echo "User $GITHUB_ACTOR is allowed to deploy to prod"
69-
exit 0
70-
fi
71-
done
72-
73-
echo "User $GITHUB_ACTOR is NOT allowed to deploy to prod"
74-
exit 1
75-
7699
- name: Configure AWS credentials
77100
uses: aws-actions/configure-aws-credentials@v4
78101
with:
79-
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ inputs.deployment_env == 'prod' && secrets.AWS_ROLE_NAME_PROD || secrets.AWS_ROLE_NAME_STAGING }}
80-
aws-region: ${{ env.AWS_REGION }}
102+
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.AWS_ROLE_NAME }}
103+
aws-region: ${{ inputs.aws_region }}
81104

82-
- name: Determine S3 path
83-
id: s3path
84-
run: |
85-
SAFE_REPO="${GITHUB_REPOSITORY//\//-}"
86-
if [[ "${{ inputs.deployment_env }}" == "prod" ]]; then
87-
BUCKET="nginx-org-prod"
88-
PATH_PART="preview"
89-
PUBLIC_URL="${{ inputs.url_prod }}"
90-
else
91-
BUCKET="nginx-org-staging"
92-
PATH_PART="previews/${GITHUB_SHA}"
93-
PUBLIC_URL="${{ inputs.url_staging }}/${GITHUB_SHA}/"
94-
fi
95-
echo "bucket=$BUCKET" >> $GITHUB_OUTPUT
96-
echo "path=$PATH_PART" >> $GITHUB_OUTPUT
97-
echo "s3_uri=s3://$BUCKET/$SAFE_REPO/$PATH_PART/" >> $GITHUB_OUTPUT
98-
echo "public_url=$PUBLIC_URL" >> $GITHUB_OUTPUT
99-
echo "safe_repo=$SAFE_REPO" >> $GITHUB_OUTPUT
100-
101-
- name: Build site
105+
- name: Build
106+
if: ${{ inputs.deployment_env == 'staging' }}
102107
run: |
103108
set -e
104109
make all
@@ -113,28 +118,81 @@ jobs:
113118
echo "Error: Build did not create www/ directory"
114119
exit 1
115120
fi
116-
121+
117122
- name: Add deployment metadata
123+
if: ${{ inputs.deployment_env == 'staging' }}
118124
run: |
119125
TIMESTAMP="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
120126
mkdir -p meta
121127
echo "$GITHUB_SHA deployed at $TIMESTAMP" > meta/.deployed.txt
122-
{
123-
echo "sha=$GITHUB_SHA"
124-
echo "repo=$GITHUB_REPOSITORY"
125-
echo "actor=$GITHUB_ACTOR"
126-
echo "timestamp=$TIMESTAMP"
127-
} > meta/.tags.txt
128+
echo "actor=$GITHUB_ACTOR repo=$GITHUB_REPOSITORY" >> meta/.deployed.txt
128129
cp meta/.deployed.txt www/
129-
cp meta/.tags.txt www/
130-
130+
131+
- name: Compute safe repo name
132+
id: vars
133+
run: |
134+
echo "safe_repo=${GITHUB_REPOSITORY//\//-}" >> "$GITHUB_OUTPUT"
135+
131136
- name: Sync www/ to S3
132137
run: |
133-
aws s3 sync www/ s3://${{ steps.s3path.outputs.bucket }}/${{ steps.s3path.outputs.safe_repo }}/${{ steps.s3path.outputs.path }}/ --delete --exact-timestamps
138+
aws s3 sync \
139+
www/ \
140+
s3://${{ inputs.s3_bucket }}/${{ steps.vars.outputs.safe_repo }}/staging/${GITHUB_SHA}/ \
141+
--delete --exact-timestamps
134142
135-
- name: Show uploaded files
143+
- name: Deployment summary
144+
run: |
145+
{
146+
echo "### Deployment Summary"
147+
echo ""
148+
echo "| Key | Value |"
149+
echo "|------------------|-------|"
150+
echo "| deployment_env | ${{ inputs.deployment_env }} |"
151+
echo "| repository | $GITHUB_REPOSITORY |"
152+
echo "| actor | $GITHUB_ACTOR |"
153+
echo "| commit | $GITHUB_SHA |"
154+
echo "| Public URL | https://${{ inputs.url_staging }}/${GITHUB_SHA} |"
155+
} >> $GITHUB_STEP_SUMMARY
156+
157+
build-prod:
158+
name: build-prod
159+
runs-on: ubuntu-latest
160+
needs: check-if-allowed
161+
if: ${{ inputs.deployment_env == 'prod' }}
162+
163+
steps:
164+
- name: Configure AWS credentials
165+
uses: aws-actions/configure-aws-credentials@v4
166+
with:
167+
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.AWS_ROLE_NAME }}
168+
aws-region: ${{ inputs.aws_region }}
169+
170+
- name: Compute safe repo name
171+
id: vars
172+
run: |
173+
echo "safe_repo=${GITHUB_REPOSITORY//\//-}" >> "$GITHUB_OUTPUT"
174+
175+
- name: Check prod deployment
176+
run: |
177+
DEPLOYED_URL="${{ inputs.url_staging }}/${GITHUB_SHA}/.deployed.txt"
178+
for i in {1..10}; do
179+
DEPLOYED_SHA=$(curl -fsSL "$DEPLOYED_URL" 2>/dev/null | awk '{ print $1 }' || echo "")
180+
if [ "$DEPLOYED_SHA" = "$GITHUB_SHA" ]; then
181+
exit 0
182+
else
183+
sleep 60
184+
fi
185+
done
186+
187+
echo "Error: wrong SHA while requesting $DEPLOYED_URL"
188+
exit 1
189+
190+
- name: Sync www/ to S3
136191
run: |
137-
aws s3 ls s3://${{ steps.s3path.outputs.bucket }}/${{ steps.s3path.outputs.safe_repo }}/${{ steps.s3path.outputs.path }}/ --recursive
192+
aws s3 sync \
193+
s3://${{ inputs.s3_bucket }}/${{ steps.vars.outputs.safe_repo }}/staging/${GITHUB_SHA}/ \
194+
s3://${{ inputs.s3_bucket }}/${{ steps.vars.outputs.safe_repo }}/prod/ \
195+
--delete --exact-timestamps
138196
139197
- name: Deployment summary
140198
run: |
@@ -147,6 +205,5 @@ jobs:
147205
echo "| repository | $GITHUB_REPOSITORY |"
148206
echo "| actor | $GITHUB_ACTOR |"
149207
echo "| commit | $GITHUB_SHA |"
150-
echo "| S3 path | ${{ steps.s3path.outputs.s3_uri }} |"
151-
echo "| Public URL | ${{ steps.s3path.outputs.public_url }} |"
208+
echo "| Public URL | https://${{ inputs.url_prod }} |"
152209
} >> $GITHUB_STEP_SUMMARY

0 commit comments

Comments
 (0)