-
Notifications
You must be signed in to change notification settings - Fork 0
161 lines (143 loc) · 6.08 KB
/
Copy pathrelease-nightly.yml
File metadata and controls
161 lines (143 loc) · 6.08 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
name: Release (nightly)
on:
workflow_dispatch:
inputs:
dry_run:
description: "Dry run — skip tag push and build (for testing)"
required: false
type: boolean
default: false
permissions:
contents: write
jobs:
# ── Step 1: Read master version, compute timestamped tag, push ───
prepare:
runs-on: ubuntu-latest
outputs:
tag: ${{ steps.resolve.outputs.tag }}
version: ${{ steps.resolve.outputs.version }}
base_version: ${{ steps.resolve.outputs.base_version }}
steps:
- name: Checkout master
uses: actions/checkout@v6
with:
ref: master
fetch-depth: 0
ssh-key: ${{ secrets.RELEASE_DEPLOY_KEY }}
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "24"
- name: Setup pnpm
uses: pnpm/action-setup@v6
- name: Resolve nightly version
id: resolve
run: |
BASE=$(node -p "require('./package.json').version")
if ! echo "$BASE" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "::error::master's package.json version must be plain X.Y.Z (got '$BASE'). The previous stable release likely failed to push the patch bump."
exit 1
fi
TIMESTAMP=$(date -u +%Y%m%d%H%M)
VERSION="${BASE}-nightly.${TIMESTAMP}"
TAG="v${VERSION}"
if git rev-parse "$TAG" >/dev/null 2>&1; then
echo "::error::Tag $TAG already exists (try again in a minute)."
exit 1
fi
echo "base_version=$BASE" >> "$GITHUB_OUTPUT"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
echo "Resolved nightly tag: $TAG"
- name: Stage nightly commit (not pushed to master)
run: |
node -e "
const fs = require('fs');
const p = JSON.parse(fs.readFileSync('package.json', 'utf8'));
p.version = '${{ steps.resolve.outputs.version }}';
fs.writeFileSync('package.json', JSON.stringify(p, null, 2) + '\n');
"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add package.json
git commit -m "release: ${{ steps.resolve.outputs.tag }}"
git tag "${{ steps.resolve.outputs.tag }}"
- name: Push tag only
if: ${{ !inputs.dry_run }}
run: |
# Push the tag without updating master — the transient commit is
# reachable only via the tag. master remains at plain X.Y.Z.
git push origin "${{ steps.resolve.outputs.tag }}"
# ── Step 2: Build installers for each platform ───────────────────
build:
needs: prepare
if: ${{ !inputs.dry_run }}
uses: ./.github/workflows/_build.yml
with:
tag: ${{ needs.prepare.outputs.tag }}
channel: nightly
sentry_environment: nightly
secrets:
MAC_CSC_LINK: ${{ secrets.MAC_CSC_LINK }}
MAC_CSC_KEY_PASSWORD: ${{ secrets.MAC_CSC_KEY_PASSWORD }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
# ── Step 3: Create GitHub prerelease ─────────────────────────────
release:
needs: [prepare, build]
if: ${{ !inputs.dry_run }}
runs-on: ubuntu-latest
steps:
- name: Download all build artifacts
uses: actions/download-artifact@v8
with:
path: release-assets
pattern: dist-*
merge-multiple: true
- name: List release assets
run: ls -lh release-assets
- name: Generate release notes since previous nightly
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CURRENT_TAG: ${{ needs.prepare.outputs.tag }}
run: |
previous_tag=$(gh release list --repo "${{ github.repository }}" --json tagName,isPrerelease,createdAt --limit 1000 \
--jq '[.[] | select(.isPrerelease and .tagName != env.CURRENT_TAG and (.tagName | test("-nightly\\.")))] | sort_by(.createdAt) | last | .tagName // empty')
args=(-f "tag_name=$CURRENT_TAG" -f "target_commitish=$CURRENT_TAG")
if [ -n "$previous_tag" ]; then
echo "Generating release notes since $previous_tag"
args+=(-f "previous_tag_name=$previous_tag")
else
echo "No previous nightly release found; generating default release notes."
fi
gh api repos/${{ github.repository }}/releases/generate-notes "${args[@]}" --jq .body > release-notes.md
# Upload every asset to a DRAFT release first. A draft is invisible to
# electron-updater (it isn't in releases.atom and its assets aren't
# publicly downloadable), so clients never observe a release whose
# channel manifest (nightly-mac.yml) is still mid-upload — the partial
# publish that surfaces as "Cannot find latest-mac.yml" 404s.
- name: Create GitHub prerelease (draft)
uses: softprops/action-gh-release@v3
with:
tag_name: ${{ needs.prepare.outputs.tag }}
name: Lightcode Nightly ${{ needs.prepare.outputs.tag }}
prerelease: true
draft: true
make_latest: false
body_path: release-notes.md
fail_on_unmatched_files: true
files: release-assets/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Flip draft → published only after all assets (manifests included) are
# uploaded. This is the single atomic moment the release becomes visible
# to the updater. prerelease stays true so nightly clients still match it.
- name: Publish the release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release edit "${{ needs.prepare.outputs.tag }}" \
--repo "${{ github.repository }}" \
--draft=false --prerelease