Skip to content

Commit d293d88

Browse files
authored
ci: Add workflow to automate deployment of docs (#207)
1 parent 42ed140 commit d293d88

File tree

4 files changed

+249
-0
lines changed

4 files changed

+249
-0
lines changed

.github/scripts/commit-and-push.sh

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
if [[ -z "${GITOPS_BRANCH:-}" ]]; then
5+
echo "GITOPS_BRANCH must be set."
6+
exit 1
7+
fi
8+
9+
if [[ -z "${IMAGE_TAG:-}" ]]; then
10+
echo "IMAGE_TAG must be set."
11+
exit 1
12+
fi
13+
14+
kustomization_path="k8s/yesdk/kustomization.yaml"
15+
16+
commit_msg=$(
17+
cat <<EOF
18+
Update $kustomization_path
19+
20+
Using image tag $IMAGE_TAG
21+
22+
Triggered by workflow: https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}
23+
Triggered by actor: ${GITHUB_ACTOR}
24+
EOF
25+
)
26+
27+
if git diff --exit-code --quiet; then
28+
echo "Nothing to commit. Skipped git commit/push."
29+
exit 0
30+
fi
31+
32+
git add "$kustomization_path"
33+
git commit --message "$commit_msg"
34+
35+
max_retries=10
36+
retry_count=0
37+
while [ $retry_count -lt $max_retries ]; do
38+
git fetch origin "$GITOPS_BRANCH"
39+
git rebase "origin/$GITOPS_BRANCH"
40+
41+
if git push; then
42+
echo "Push successful"
43+
break
44+
else
45+
((retry_count += 1))
46+
if [ $retry_count -ge $max_retries ]; then
47+
echo "Max retries reached. Exiting with failure."
48+
exit 1
49+
fi
50+
51+
echo "Failed to push. Retrying..."
52+
sleep 5
53+
fi
54+
done

.github/scripts/configure-git-pgp.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
if [[ -z "${PGP_KEY:-}" ]]; then
5+
echo "PGP_KEY must be set."
6+
exit 1
7+
fi
8+
9+
echo "$PGP_KEY" | gpg --import
10+
11+
key_id=$(gpg --list-secret-keys --with-colons | awk -F: '$1 == "sec" {print $5}')
12+
git config --global commit.gpgsign "true"
13+
git config --global user.signingKey "${key_id}"
14+
echo "Using PGP key for git commit signing: ${key_id}"
15+
16+
pgp_user_id=$(gpg --list-keys --with-colons "$key_id" | awk -F: '$1 == "uid" {print $10}')
17+
pgp_name=$(echo "$pgp_user_id" | cut --delimiter '<' --fields 1)
18+
pgp_email=$(echo "$pgp_user_id" | cut --delimiter '<' --fields 2 | cut --delimiter '>' --fields 1)
19+
git config --global user.name "${pgp_name}"
20+
git config --global user.email "${pgp_email}"
21+
22+
echo "Git name: ${pgp_name}"
23+
echo "Git email: ${pgp_email}"
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
if [[ -z "${GITHUB_TOKEN:-}" ]]; then
5+
echo "GITHUB_TOKEN must be set."
6+
exit 1
7+
fi
8+
9+
if [[ -z "${REF:-}" ]]; then
10+
echo "REF must be set."
11+
exit 1
12+
fi
13+
14+
ORG=${ORG:-Yubico}
15+
REPO=${REPO:-docs-gitops}
16+
KUSTOMIZATION_NAME=${KUSTOMIZATION_NAME:-docs}
17+
18+
timeout_minutes=15
19+
end_time=$(date -ud "+$timeout_minutes minutes" +%s)
20+
21+
echo "Looking for status:"
22+
echo " Repo: $ORG/$REPO"
23+
echo " Ref: $REF"
24+
echo " Status context: kustomization/$KUSTOMIZATION_NAME"
25+
echo
26+
27+
state=""
28+
message_printed=false
29+
while [[ -z "$state" ]]; do
30+
state=$(gh api "/repos/$ORG/$REPO/commits/$REF/status" | jq -r ".statuses[] | select(.context | startswith(\"kustomization/$KUSTOMIZATION_NAME/\")).state")
31+
32+
if [[ -n "$state" ]]; then
33+
echo "Status: $state"
34+
break
35+
fi
36+
37+
if [[ $(date -u +%s) -ge $end_time ]]; then
38+
echo "Deployment was not complete after $timeout_minutes minutes."
39+
exit 1
40+
fi
41+
42+
if [[ "$message_printed" == "false" ]]; then
43+
echo "Waiting for deployment to complete (timeout: $timeout_minutes minutes)..."
44+
message_printed=true
45+
fi
46+
sleep 10
47+
done
48+
49+
if [[ "$state" != "success" ]]; then
50+
exit 1
51+
fi
52+
53+
exit 0

.github/workflows/deploy-docs.yml

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
name: Deploy documentation
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
gitops-branch:
7+
type: choice
8+
description: Environment to deploy to
9+
required: true
10+
options:
11+
- dev
12+
- stage
13+
- prod
14+
image-tag:
15+
type: string
16+
description: Image tag to deploy
17+
required: true
18+
19+
permissions:
20+
id-token: write
21+
contents: read
22+
23+
jobs:
24+
deploy:
25+
name: Deploy docs
26+
runs-on: ubuntu-latest
27+
28+
steps:
29+
- name: Check out current repo
30+
uses: actions/checkout@v4
31+
with:
32+
path: self
33+
34+
- id: auth
35+
name: Authenticate to Google Cloud
36+
uses: google-github-actions/auth@v2
37+
with:
38+
workload_identity_provider: ${{ vars.GLOBAL_GCP_WORKLOAD_IDENTITY_PROVIDER }}
39+
service_account: [email protected]
40+
41+
- name: Generate GitHub App token
42+
id: generate_token
43+
uses: actions/create-github-app-token@v1
44+
with:
45+
app-id: 800408 # Yubico Docs
46+
owner: Yubico
47+
repositories: docs-gitops
48+
private-key: ${{ secrets.GH_APP_YUBICO_DOCS_PRIVATE_KEY }}
49+
50+
- name: Check out docs-gitops repo (${{ inputs.gitops-branch }} branch)
51+
uses: actions/checkout@v4
52+
with:
53+
repository: Yubico/docs-gitops
54+
ref: ${{ inputs.gitops-branch }}
55+
token: ${{ steps.generate_token.outputs.token }}
56+
path: gitops
57+
58+
- name: Update GitOps resources
59+
run: sed -i "s#/yesdk/yesdk-docserver:.*\$#/yesdk/yesdk-docserver:$IMAGE_TAG#" ./k8s/yesdk/kustomization.yaml
60+
working-directory: ./gitops
61+
env:
62+
IMAGE_TAG: "${{ inputs.image-tag }}"
63+
64+
- name: Set up commit signing
65+
run: .github/scripts/configure-git-pgp.sh
66+
env:
67+
PGP_KEY: ${{ secrets.DOCS_GITOPS_PGP_KEY }}
68+
working-directory: ./self
69+
70+
- name: Push changes to GitOps repo
71+
run: ${{ github.workspace }}/self/.github/scripts/commit-and-push.sh
72+
working-directory: ./gitops
73+
env:
74+
GITOPS_BRANCH: ${{ inputs.gitops-branch }}
75+
IMAGE_TAG: "${{ inputs.image-tag }}"
76+
77+
verify:
78+
name: Verify deployment completion
79+
runs-on: ubuntu-latest
80+
needs: deploy
81+
82+
steps:
83+
- name: Checkout
84+
uses: actions/checkout@v4
85+
86+
- name: Authenticate to Google Cloud to read commit status
87+
uses: google-github-actions/auth@v2
88+
with:
89+
workload_identity_provider: ${{ vars.GLOBAL_GCP_WORKLOAD_IDENTITY_PROVIDER }}
90+
service_account: github-commit-status-reader@prod-docs-403900.iam.gserviceaccount.com
91+
92+
- name: Generate GitHub App token
93+
id: generate_token
94+
uses: actions/create-github-app-token@v1
95+
with:
96+
app-id: 260767 # Yubico Commit Status Reader
97+
owner: Yubico
98+
repositories: docs-gitops
99+
private-key: ${{ secrets.GH_APP_YUBICO_COMMIT_STATUS_READER_PRIVATE_KEY }}
100+
101+
- name: Wait for deployment to complete
102+
run: ./.github/scripts/wait-for-commit-status.sh
103+
env:
104+
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
105+
ORG: yubico
106+
REPO: docs-gitops
107+
REF: ${{ inputs.gitops-branch }}
108+
KUSTOMIZATION_NAME: docs
109+
110+
- name: Purge Fastly cache
111+
run: >-
112+
curl
113+
-X POST
114+
-H "Accept: application/json"
115+
-H "Fastly-Key: ${{ secrets.FASTLY_API_KEY }}"
116+
"https://api.fastly.com/service/${{ secrets.FASTLY_SERVICE_ID }}/purge_all"
117+
118+
- name: Wait 30 seconds for Fastly cache to purge
119+
run: sleep 30

0 commit comments

Comments
 (0)