-
Notifications
You must be signed in to change notification settings - Fork 10
179 lines (160 loc) · 6.79 KB
/
Copy pathupload-locales.yml
File metadata and controls
179 lines (160 loc) · 6.79 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
179
name: Upload Locales to Cloudflare R2
# Triggered on version tag pushes (e.g., v0.1.0, v1.0.0-rc.1)
on:
push:
tags:
- "v*"
env:
MIX_ENV: dev
R2_BUCKET: content
# Prefix within the bucket where locale ETF files are stored.
R2_PREFIX: locales
# Maximum concurrent uploads to stay within Cloudflare API limits.
# R2 allows ~1000 PUT requests/second; we use a conservative batch
# size to avoid transient rate-limit errors.
BATCH_SIZE: 50
permissions:
contents: read
jobs:
generate-and-upload:
name: Generate and upload locale ETFs
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
# Read the data version directly from the on-disk version
# files before doing any expensive work. The version is
# derived from `priv/localize/version` (CLDR release) and
# `priv/localize/localize_patch_version` (Localize patch
# counter). No Elixir compile is required for this step.
- name: Read data version
id: version
run: |
cldr_version=$(cat priv/localize/version | tr -d '[:space:]')
patch_raw=$(cat priv/localize/localize_patch_version | tr -d '[:space:]')
# `localize_patch_version` is stored as "{cldr_version}:{patch}".
# If the recorded CLDR version matches the current one, take
# the numeric patch; otherwise treat the patch as 0.
recorded_cldr="${patch_raw%%:*}"
recorded_patch="${patch_raw##*:}"
if [ "${recorded_cldr}" = "${cldr_version}" ]; then
patch_version="${recorded_patch}"
else
patch_version="0"
fi
data_version="v${cldr_version}.${patch_version}"
echo "data_version=${data_version}" >> "$GITHUB_OUTPUT"
echo "Data version: ${data_version}"
- name: Install rclone
run: |
curl -fsSL https://rclone.org/install.sh | sudo bash
- name: Configure rclone for Cloudflare R2
env:
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
R2_ACCOUNT_ID: ${{ secrets.R2_ACCOUNT_ID }}
run: |
mkdir -p ~/.config/rclone
cat > ~/.config/rclone/rclone.conf << EOF
[r2]
type = s3
provider = Cloudflare
access_key_id = ${R2_ACCESS_KEY_ID}
secret_access_key = ${R2_SECRET_ACCESS_KEY}
endpoint = https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com
acl = private
no_check_bucket = true
EOF
# Short-circuit: if the target R2 prefix already contains ETF
# files for this data_version, there is nothing to do. This
# avoids re-generating and re-uploading the same data when a
# release tag is pushed without a corresponding CLDR or patch
# version bump.
- name: Check if data version already exists on R2
id: check_existing
env:
DATA_VERSION: ${{ steps.version.outputs.data_version }}
run: |
existing=$(rclone lsf "r2:${R2_BUCKET}/${R2_PREFIX}/${DATA_VERSION}/" --include "*.etf" 2>/dev/null | wc -l | tr -d '[:space:]')
echo "Found ${existing} existing ETF file(s) at r2:${R2_BUCKET}/${R2_PREFIX}/${DATA_VERSION}/"
if [ "${existing}" -gt 0 ]; then
echo "skip=true" >> "$GITHUB_OUTPUT"
echo "::notice::Data version ${DATA_VERSION} already exists on R2 with ${existing} file(s); skipping generation and upload."
else
echo "skip=false" >> "$GITHUB_OUTPUT"
fi
- name: Set up Elixir
if: steps.check_existing.outputs.skip != 'true'
uses: erlef/setup-beam@v1
with:
elixir-version: "1.19"
otp-version: "28"
- name: Restore dependency cache
if: steps.check_existing.outputs.skip != 'true'
uses: actions/cache@v4
with:
path: |
deps
_build
key: mix-locales-${{ hashFiles('mix.lock') }}
restore-keys: |
mix-locales-
- name: Install dependencies
if: steps.check_existing.outputs.skip != 'true'
run: mix deps.get
- name: Compile
if: steps.check_existing.outputs.skip != 'true'
run: mix compile
- name: Generate locale ETFs
if: steps.check_existing.outputs.skip != 'true'
run: mix localize.generate_locales
- name: Verify generated locales
if: steps.check_existing.outputs.skip != 'true'
run: |
count=$(ls priv/localize/locales/*.etf 2>/dev/null | wc -l)
echo "Generated ${count} locale ETF files"
if [ "$count" -lt 100 ]; then
echo "::error::Expected at least 100 locale files, got ${count}"
exit 1
fi
- name: Upload locales to R2
if: steps.check_existing.outputs.skip != 'true'
env:
DATA_VERSION: ${{ steps.version.outputs.data_version }}
run: |
echo "Uploading to r2:${R2_BUCKET}/${R2_PREFIX}/${DATA_VERSION}/"
echo "Files: $(ls priv/localize/locales/*.etf | wc -l)"
# Use rclone sync with bandwidth and concurrency limits.
# --transfers: concurrent file transfers (R2 allows ~1000 PUT/s,
# we use a conservative limit via BATCH_SIZE).
# --checkers: concurrent hash checks.
# --s3-upload-concurrency: per-file multipart concurrency.
rclone sync \
priv/localize/locales/ \
"r2:${R2_BUCKET}/${R2_PREFIX}/${DATA_VERSION}/" \
--include "*.etf" \
--transfers ${BATCH_SIZE} \
--checkers 8 \
--s3-upload-concurrency 2 \
--stats 10s \
--stats-one-line \
--verbose
- name: Verify upload
if: steps.check_existing.outputs.skip != 'true'
env:
DATA_VERSION: ${{ steps.version.outputs.data_version }}
run: |
uploaded=$(rclone ls "r2:${R2_BUCKET}/${R2_PREFIX}/${DATA_VERSION}/" | wc -l)
local_count=$(ls priv/localize/locales/*.etf | wc -l)
echo "Uploaded: ${uploaded}, Local: ${local_count}"
if [ "$uploaded" -ne "$local_count" ]; then
echo "::warning::Upload count mismatch: ${uploaded} uploaded vs ${local_count} local"
fi
echo "Upload complete: ${uploaded} locale files to ${R2_BUCKET}/${R2_PREFIX}/${DATA_VERSION}/"
- name: Skipped summary
if: steps.check_existing.outputs.skip == 'true'
env:
DATA_VERSION: ${{ steps.version.outputs.data_version }}
run: |
echo "Skipped: data version ${DATA_VERSION} already present on R2 at ${R2_BUCKET}/${R2_PREFIX}/${DATA_VERSION}/"
echo "Nothing was regenerated or uploaded. Bump the CLDR or Localize patch version and push a new tag to trigger a real upload."