-
Notifications
You must be signed in to change notification settings - Fork 1
178 lines (165 loc) · 6.04 KB
/
Copy pathupdate_versions.yml
File metadata and controls
178 lines (165 loc) · 6.04 KB
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
name: Update versions
# Refresh the SDK versions shown on the product family pages from the canonical feed
# https://products.groupdocs.com/versions.json. Upstream regenerates that file twice a day
# (06:00 + 18:00 UTC via its own GitHub Action), so we run +10 minutes later.
#
# scripts/update_versions.py trims the feed to just the fields we render (version + release-notes URL)
# and sorts keys, so data/versions.json only changes when a version actually moves (not on the
# upstream's generatedAt/downloads churn).
#
# Single-branch model: the data file is committed once, to `main`, and staging is redeployed.
# Production is NOT redeployed by default — see AUTO_PROMOTE_VERSIONS below.
#
# Note this job commits with GITHUB_TOKEN, whose pushes deliberately do not trigger other
# workflows. That is why it calls the deploy jobs itself, and why a deploy marker in its commit
# message would be inert — do not add one.
on:
schedule:
- cron: '10 6,18 * * *' # 06:10 + 18:10 UTC (+10 min after upstream publishes versions.json)
workflow_dispatch:
inputs:
force:
description: Redeploy even if versions did not change
type: boolean
default: false
environment:
description: When forcing, which environment(s) to redeploy
type: choice
options: [both, production, staging]
default: staging
permissions:
contents: write
concurrency:
group: update-versions
cancel-in-progress: false
jobs:
sync:
runs-on: ubuntu-latest
outputs:
do_staging: ${{ steps.sync.outputs.do_staging }}
do_prod: ${{ steps.sync.outputs.do_prod }}
steps:
- uses: actions/checkout@v4
with:
ref: main
fetch-depth: 0
- name: Fetch + transform versions.json
run: python3 scripts/update_versions.py --out /tmp/versions.json
- name: Commit data/versions.json on main
id: sync
env:
FORCE: ${{ github.event.inputs.force || 'false' }}
FORCE_ENV: ${{ github.event.inputs.environment || 'staging' }}
# Repo variable, default off. When true, a version change also publishes to production.
# Leave it off unless you want the site continuously deployed: `main` is now the single
# branch, so a production run here publishes EVERY product's current content, not just
# the version strings.
AUTO_PROMOTE: ${{ vars.AUTO_PROMOTE_VERSIONS || 'false' }}
run: |
set -euo pipefail
git config user.name "groupdocs-version-bot"
git config user.email "groupdocs-version-bot@users.noreply.github.com"
git fetch origin main
git checkout -B main origin/main
cp /tmp/versions.json data/versions.json
changed=false
if git diff --quiet -- data/versions.json; then
echo "no version changes"
else
git add data/versions.json
git commit -m "Update SDK versions from products.groupdocs.com/versions.json"
# `main` is now the only branch, so it also absorbs every product sync. Retry on a
# racing push rather than failing (or, worse, silently losing) the update.
pushed=false
for i in 1 2 3 4 5; do
if git push origin main; then pushed=true; break; fi
sleep $(( i * 5 ))
git fetch origin main
git rebase origin/main
done
if [ "$pushed" != true ]; then
echo "::error::could not push data/versions.json after 5 attempts"
exit 1
fi
changed=true
echo "versions updated"
fi
do_staging=$changed
do_prod=false
if [ "$AUTO_PROMOTE" = "true" ] && [ "$changed" = "true" ]; then
do_prod=true
fi
# Manual dispatch with force: redeploy the selected environment(s) even with no change.
if [ "$FORCE" = "true" ]; then
case "$FORCE_ENV" in
production) do_prod=true ;;
staging) do_staging=true ;;
*) do_prod=true; do_staging=true ;;
esac
fi
{
echo "do_staging=$do_staging"
echo "do_prod=$do_prod"
} >> "$GITHUB_OUTPUT"
echo "changed=$changed do_staging=$do_staging do_prod=$do_prod"
# Rebuild + redeploy the product family pages with the new versions. Only the 15 product builds
# render versions (home/aggregates don't), so we skip them. Both environments build `main` — the
# single deploy branch.
deploy_staging:
needs: sync
if: needs.sync.outputs.do_staging == 'true'
strategy:
fail-fast: false
matrix:
product_family:
- annotation
- assembly
- classification
- comparison
- conversion
- editor
- markdown
- merger
- metadata
- parser
- redaction
- search
- signature
- viewer
- watermark
uses: ./.github/workflows/deploy_product.yml
with:
product_family: ${{ matrix.product_family }}
environment: staging
ref: main
secrets: inherit
deploy_production:
needs: [sync, deploy_staging]
# `always()` so an explicit production force still runs when deploy_staging was skipped.
if: ${{ always() && needs.sync.outputs.do_prod == 'true'
&& needs.deploy_staging.result != 'failure' && needs.deploy_staging.result != 'cancelled' }}
strategy:
fail-fast: false
matrix:
product_family:
- annotation
- assembly
- classification
- comparison
- conversion
- editor
- markdown
- merger
- metadata
- parser
- redaction
- search
- signature
- viewer
- watermark
uses: ./.github/workflows/deploy_product.yml
with:
product_family: ${{ matrix.product_family }}
environment: production
ref: main
secrets: inherit