Skip to content

Commit 2fbc823

Browse files
committed
ci: gate upstream check by etag before downloading dmg
1 parent 5cda965 commit 2fbc823

2 files changed

Lines changed: 100 additions & 26 deletions

File tree

.github/workflows/check-upstream.yml

Lines changed: 95 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,37 +26,92 @@ jobs:
2626
- name: Install dependencies
2727
run: npm install
2828

29+
- name: Determine latest local tag
30+
id: latest_tag
31+
run: |
32+
TAG="$(git tag -l 'v*' | sort -V | tail -n 1 || true)"
33+
TAG="${TAG#v}"
34+
echo "version=${TAG}" >> "${GITHUB_OUTPUT}"
35+
36+
- name: Check upstream DMG ETag
37+
id: etag
38+
run: |
39+
set -euo pipefail
40+
URL="https://persistent.oaistatic.com/codex-app-prod/Codex.dmg"
41+
STORED_ETAG=""
42+
if [[ -f upstream-etag.txt ]]; then
43+
STORED_ETAG="$(tr -d '\r\n' < upstream-etag.txt)"
44+
fi
45+
46+
HEADER_FILE="$(mktemp)"
47+
STATUS_CODE=""
48+
if [[ -n "${STORED_ETAG}" ]]; then
49+
STATUS_CODE="$(curl -sS -I -D "${HEADER_FILE}" -o /dev/null -w '%{http_code}' -H "If-None-Match: ${STORED_ETAG}" "${URL}")"
50+
else
51+
STATUS_CODE="$(curl -sS -I -D "${HEADER_FILE}" -o /dev/null -w '%{http_code}' "${URL}")"
52+
fi
53+
54+
if [[ "${STATUS_CODE}" == "304" ]]; then
55+
echo "changed=false" >> "${GITHUB_OUTPUT}"
56+
echo "etag=${STORED_ETAG}" >> "${GITHUB_OUTPUT}"
57+
echo "No upstream DMG update (304 Not Modified)."
58+
exit 0
59+
fi
60+
61+
if [[ "${STATUS_CODE}" != "200" ]]; then
62+
echo "Unexpected status from upstream HEAD: ${STATUS_CODE}" >&2
63+
cat "${HEADER_FILE}" >&2 || true
64+
exit 1
65+
fi
66+
67+
CURRENT_ETAG="$(
68+
awk 'BEGIN{IGNORECASE=1} /^etag:/ {sub(/\r$/,"",$2); print $2; exit}' "${HEADER_FILE}"
69+
)"
70+
71+
if [[ -z "${CURRENT_ETAG}" ]]; then
72+
echo "Missing ETag header from upstream; cannot do safe change detection." >&2
73+
cat "${HEADER_FILE}" >&2 || true
74+
exit 1
75+
fi
76+
77+
echo "etag=${CURRENT_ETAG}" >> "${GITHUB_OUTPUT}"
78+
if [[ "${CURRENT_ETAG}" == "${STORED_ETAG}" ]]; then
79+
echo "changed=false" >> "${GITHUB_OUTPUT}"
80+
echo "No upstream DMG update (ETag unchanged)."
81+
else
82+
echo "changed=true" >> "${GITHUB_OUTPUT}"
83+
echo "Upstream DMG changed: ${STORED_ETAG} -> ${CURRENT_ETAG}"
84+
fi
85+
2986
- name: Download Codex DMG
87+
if: steps.etag.outputs.changed == 'true'
3088
run: curl -fL "https://persistent.oaistatic.com/codex-app-prod/Codex.dmg" -o Codex.dmg
3189

3290
- name: Read upstream Codex version
91+
if: steps.etag.outputs.changed == 'true'
3392
id: upstream
3493
run: |
3594
VERSION="$(bash scripts/get-codex-version.sh ./Codex.dmg)"
3695
echo "version=${VERSION}" >> "${GITHUB_OUTPUT}"
3796
38-
- name: Determine latest local tag
39-
id: latest_tag
40-
run: |
41-
TAG="$(git tag -l 'v*' | sort -V | tail -n 1 || true)"
42-
TAG="${TAG#v}"
43-
echo "version=${TAG}" >> "${GITHUB_OUTPUT}"
44-
45-
- name: Create commit and tag when new version exists
46-
if: steps.upstream.outputs.version != steps.latest_tag.outputs.version
97+
- name: Create commit and optional tag when upstream changed
98+
if: steps.etag.outputs.changed == 'true'
4799
env:
48100
RELEASE_PAT: ${{ secrets.RELEASE_PAT }}
49101
run: |
50102
set -euo pipefail
103+
NEW_ETAG="${{ steps.etag.outputs.etag }}"
51104
NEW_VERSION="${{ steps.upstream.outputs.version }}"
52-
NEW_TAG="v${NEW_VERSION}"
53-
54-
if git rev-parse "${NEW_TAG}" >/dev/null 2>&1; then
55-
echo "Tag ${NEW_TAG} already exists. Nothing to do."
56-
exit 0
105+
LATEST_LOCAL_VERSION="${{ steps.latest_tag.outputs.version }}"
106+
VERSION_CHANGED="false"
107+
if [[ "${NEW_VERSION}" != "${LATEST_LOCAL_VERSION}" ]]; then
108+
VERSION_CHANGED="true"
57109
fi
58110
59-
echo "${NEW_VERSION}" > upstream-version.txt
111+
echo "${NEW_ETAG}" > upstream-etag.txt
112+
if [[ "${VERSION_CHANGED}" == "true" ]]; then
113+
echo "${NEW_VERSION}" > upstream-version.txt
114+
fi
60115
61116
git config user.name "github-actions[bot]"
62117
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
@@ -65,17 +120,35 @@ jobs:
65120
git remote set-url origin "https://x-access-token:${RELEASE_PAT}@github.com/${GITHUB_REPOSITORY}.git"
66121
fi
67122
68-
if ! git diff --quiet -- upstream-version.txt; then
123+
git add upstream-etag.txt
124+
if [[ "${VERSION_CHANGED}" == "true" ]]; then
69125
git add upstream-version.txt
70-
git commit -m "chore: bump upstream Codex to ${NEW_VERSION}"
126+
fi
127+
128+
if ! git diff --cached --quiet; then
129+
if [[ "${VERSION_CHANGED}" == "true" ]]; then
130+
COMMIT_MSG="chore: bump upstream Codex to ${NEW_VERSION}"
131+
else
132+
COMMIT_MSG="chore: update upstream Codex etag"
133+
fi
134+
git commit -m "${COMMIT_MSG}"
71135
git push origin HEAD:${GITHUB_REF_NAME}
72136
else
73-
echo "Version file unchanged, skipping commit."
137+
echo "Tracking files unchanged, skipping commit."
74138
fi
75139
76-
git tag "${NEW_TAG}"
77-
git push origin "${NEW_TAG}"
140+
if [[ "${VERSION_CHANGED}" == "true" ]]; then
141+
NEW_TAG="v${NEW_VERSION}"
142+
if git rev-parse "${NEW_TAG}" >/dev/null 2>&1; then
143+
echo "Tag ${NEW_TAG} already exists. Nothing to do."
144+
exit 0
145+
fi
146+
git tag "${NEW_TAG}"
147+
git push origin "${NEW_TAG}"
148+
else
149+
echo "Upstream DMG changed but app version stayed at ${NEW_VERSION}; skipping tag."
150+
fi
78151
79152
- name: No update
80-
if: steps.upstream.outputs.version == steps.latest_tag.outputs.version
81-
run: echo "Upstream version unchanged: ${{ steps.upstream.outputs.version }}"
153+
if: steps.etag.outputs.changed != 'true'
154+
run: echo "Upstream DMG unchanged (ETag: ${{ steps.etag.outputs.etag }})"

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,11 @@ GitHub Actions will automatically:
7575

7676
Workflow [`check-upstream.yml`](.github/workflows/check-upstream.yml) runs daily and:
7777

78-
- Downloads latest upstream `Codex.dmg`
79-
- Extracts Codex app version from `app.asar/package.json`
80-
- Compares with latest git tag (`v*`)
81-
- If newer: updates `upstream-version.txt`, commits, and creates a new tag `v<codex-version>`
78+
- Sends a `HEAD` request to upstream `Codex.dmg` and checks `ETag` first
79+
- If `ETag` is unchanged: skip download
80+
- If `ETag` changed: download `Codex.dmg`, extract Codex app version from `app.asar/package.json`
81+
- Compares that version with latest git tag (`v*`)
82+
- If newer: updates `upstream-version.txt`, updates `upstream-etag.txt`, commits, and creates a new tag `v<codex-version>`
8283

8384
That new tag triggers the release workflow, which publishes new `.deb`, `.AppImage`, and refreshed APT metadata.
8485

0 commit comments

Comments
 (0)