Skip to content

Commit 53bd538

Browse files
committed
feat!: wire channel input, fix dist bundle
Signed-off-by: Sam Gammon <sam@elide.ventures>
1 parent 2ecf6ba commit 53bd538

File tree

6 files changed

+127
-66
lines changed

6 files changed

+127
-66
lines changed

__tests__/releases.test.ts

Lines changed: 82 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -48,128 +48,154 @@ describe('buildDownloadUrl', () => {
4848
whichMock.mockResolvedValue('')
4949
})
5050

51-
// --- Elide 1.0 tests (release channel, semver tags) ---
51+
// --- Channel: release (Elide 1.0) ---
5252

53-
it('should build correct URL for Elide 1.0 linux-amd64', async () => {
53+
it('should build release channel URL for linux-amd64', async () => {
5454
const options = buildOptions({
5555
os: 'linux',
5656
arch: 'amd64',
57-
version: '1.0.0'
57+
version: '1.0.0',
58+
channel: 'release'
59+
})
60+
const { url } = await buildDownloadUrl(options, {
61+
tag_name: '1.0.0',
62+
userProvided: true
5863
})
59-
const version = { tag_name: '1.0.0', userProvided: true }
60-
const { url } = await buildDownloadUrl(options, version)
6164
expect(url.toString()).toBe(
6265
'https://elide.zip/artifacts/release/1.0.0/elide.linux-amd64.tgz'
6366
)
6467
})
6568

66-
it('should build correct URL for Elide 1.0 macos-arm64 (darwin->macos, aarch64->arm64)', async () => {
69+
it('should build release channel URL for macos-arm64', async () => {
6770
const options = buildOptions({
6871
os: 'darwin',
6972
arch: 'aarch64',
70-
version: '1.0.0'
73+
version: '1.0.0',
74+
channel: 'release'
75+
})
76+
const { url } = await buildDownloadUrl(options, {
77+
tag_name: '1.0.0',
78+
userProvided: true
7179
})
72-
const version = { tag_name: '1.0.0', userProvided: true }
73-
const { url } = await buildDownloadUrl(options, version)
7480
expect(url.toString()).toBe(
7581
'https://elide.zip/artifacts/release/1.0.0/elide.macos-arm64.tgz'
7682
)
7783
})
7884

79-
it('should build correct URL for Elide 1.0 macos-amd64', async () => {
85+
it('should build release channel URL for macos-amd64', async () => {
8086
const options = buildOptions({
8187
os: 'darwin',
8288
arch: 'amd64',
83-
version: '1.0.0'
89+
version: '1.0.0',
90+
channel: 'release'
91+
})
92+
const { url } = await buildDownloadUrl(options, {
93+
tag_name: '1.0.0',
94+
userProvided: true
8495
})
85-
const version = { tag_name: '1.0.0', userProvided: true }
86-
const { url } = await buildDownloadUrl(options, version)
8796
expect(url.toString()).toBe(
8897
'https://elide.zip/artifacts/release/1.0.0/elide.macos-amd64.tgz'
8998
)
9099
})
91100

92-
it('should build correct URL for Elide 1.0 windows-amd64', async () => {
101+
it('should build release channel URL for windows-amd64', async () => {
93102
const options = buildOptions({
94103
os: 'windows',
95104
arch: 'amd64',
96-
version: '1.0.0'
105+
version: '1.0.0',
106+
channel: 'release'
107+
})
108+
const { url, archiveType } = await buildDownloadUrl(options, {
109+
tag_name: '1.0.0',
110+
userProvided: true
97111
})
98-
const version = { tag_name: '1.0.0', userProvided: true }
99-
const { url, archiveType } = await buildDownloadUrl(options, version)
100112
expect(url.toString()).toBe(
101113
'https://elide.zip/artifacts/release/1.0.0/elide.windows-amd64.zip'
102114
)
103115
expect(archiveType).toBe(ArchiveType.ZIP)
104116
})
105117

106-
// --- Classic tests (pre-1.0 versions like 1.0.0-beta10) ---
118+
// --- Channel: release (Classic pre-1.0) ---
107119

108-
it('should build correct URL for classic release (1.0.0-beta10)', async () => {
120+
it('should build release channel URL for classic 1.0.0-beta10', async () => {
109121
const options = buildOptions({
110122
os: 'linux',
111123
arch: 'amd64',
112-
version: '1.0.0-beta10'
124+
version: '1.0.0-beta10',
125+
channel: 'release'
126+
})
127+
const { url } = await buildDownloadUrl(options, {
128+
tag_name: '1.0.0-beta10',
129+
userProvided: true
113130
})
114-
const version = { tag_name: '1.0.0-beta10', userProvided: true }
115-
const { url } = await buildDownloadUrl(options, version)
116131
expect(url.toString()).toBe(
117132
'https://elide.zip/artifacts/release/1.0.0-beta10/elide.linux-amd64.tgz'
118133
)
119134
})
120135

121-
it('should build correct URL for classic darwin-aarch64', async () => {
136+
it('should build release channel URL for classic darwin-aarch64', async () => {
122137
const options = buildOptions({
123138
os: 'darwin',
124139
arch: 'aarch64',
125-
version: '1.0.0-alpha7'
140+
version: '1.0.0-alpha7',
141+
channel: 'release'
142+
})
143+
const { url } = await buildDownloadUrl(options, {
144+
tag_name: '1.0.0-alpha7',
145+
userProvided: true
126146
})
127-
const version = { tag_name: '1.0.0-alpha7', userProvided: true }
128-
const { url } = await buildDownloadUrl(options, version)
129147
expect(url.toString()).toBe(
130148
'https://elide.zip/artifacts/release/1.0.0-alpha7/elide.macos-arm64.tgz'
131149
)
132150
})
133151

134-
// --- Channel tests ---
152+
// --- Channel: nightly (default) ---
135153

136-
it('should use nightly channel and strip prefix from nightly tags', async () => {
154+
it('should default to nightly channel', async () => {
137155
const options = buildOptions({
138156
os: 'linux',
139157
arch: 'amd64',
140158
version: '1.0.0'
141159
})
142-
const version = { tag_name: 'nightly-20260323', userProvided: false }
143-
const { url, archiveType } = await buildDownloadUrl(options, version)
160+
const { url } = await buildDownloadUrl(options, {
161+
tag_name: '1.0.0',
162+
userProvided: true
163+
})
144164
expect(url.toString()).toBe(
145-
'https://elide.zip/artifacts/nightly/20260323/elide.linux-amd64.tgz'
165+
'https://elide.zip/artifacts/nightly/1.0.0/elide.linux-amd64.tgz'
146166
)
147-
expect(archiveType).toBe(ArchiveType.GZIP)
148167
})
149168

150-
it('should use preview channel and strip prefix from preview tags', async () => {
169+
it('should use nightly/latest when version is latest', async () => {
151170
const options = buildOptions({
152-
os: 'darwin',
153-
arch: 'aarch64',
154-
version: '1.0.0'
171+
os: 'linux',
172+
arch: 'amd64',
173+
version: 'latest'
174+
})
175+
const { url } = await buildDownloadUrl(options, {
176+
tag_name: 'ignored',
177+
userProvided: false
155178
})
156-
const version = { tag_name: 'preview-20260323', userProvided: false }
157-
const { url } = await buildDownloadUrl(options, version)
158179
expect(url.toString()).toBe(
159-
'https://elide.zip/artifacts/preview/20260323/elide.macos-arm64.tgz'
180+
'https://elide.zip/artifacts/nightly/latest/elide.linux-amd64.tgz'
160181
)
161182
})
162183

163-
it('should use "latest" revision when version is latest', async () => {
184+
// --- Channel: preview ---
185+
186+
it('should use preview channel when specified', async () => {
164187
const options = buildOptions({
165-
os: 'linux',
166-
arch: 'amd64',
167-
version: 'latest'
188+
os: 'darwin',
189+
arch: 'aarch64',
190+
version: 'latest',
191+
channel: 'preview'
192+
})
193+
const { url } = await buildDownloadUrl(options, {
194+
tag_name: 'ignored',
195+
userProvided: false
168196
})
169-
const version = { tag_name: 'nightly-20260323', userProvided: false }
170-
const { url } = await buildDownloadUrl(options, version)
171197
expect(url.toString()).toBe(
172-
'https://elide.zip/artifacts/nightly/latest/elide.linux-amd64.tgz'
198+
'https://elide.zip/artifacts/preview/latest/elide.macos-arm64.tgz'
173199
)
174200
})
175201

@@ -181,8 +207,10 @@ describe('buildDownloadUrl', () => {
181207
arch: 'amd64',
182208
version: 'latest'
183209
})
184-
const version = { tag_name: 'nightly-20260323', userProvided: false }
185-
const { url, archiveType } = await buildDownloadUrl(options, version)
210+
const { url, archiveType } = await buildDownloadUrl(options, {
211+
tag_name: 'ignored',
212+
userProvided: false
213+
})
186214
expect(url.toString()).toBe(
187215
'https://elide.zip/artifacts/nightly/latest/elide.windows-amd64.zip'
188216
)
@@ -194,10 +222,13 @@ describe('buildDownloadUrl', () => {
194222
const options = buildOptions({
195223
os: 'linux',
196224
arch: 'amd64',
197-
version: '1.0.0'
225+
version: '1.0.0',
226+
channel: 'release'
227+
})
228+
const { url, archiveType } = await buildDownloadUrl(options, {
229+
tag_name: '1.0.0',
230+
userProvided: true
198231
})
199-
const version = { tag_name: '1.0.0', userProvided: true }
200-
const { url, archiveType } = await buildDownloadUrl(options, version)
201232
expect(url.toString()).toBe(
202233
'https://elide.zip/artifacts/release/1.0.0/elide.linux-amd64.txz'
203234
)

action.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ inputs:
1111
required: false
1212
default: 'latest'
1313

14+
channel:
15+
description: 'Channel'
16+
required: false
17+
default: 'nightly'
18+
1419
os:
1520
description: 'OS'
1621
required: false

src/install-apt.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ export async function installViaApt(
4343

4444
// 2. Add apt source
4545
core.info('Adding Elide apt repository')
46-
const sourceLine = `deb [arch=${arch} signed-by=/usr/share/keyrings/elide.gpg] https://dl.elide.dev nightly main`
46+
const channel = options.channel || 'nightly'
47+
const sourceLine = `deb [arch=${arch} signed-by=/usr/share/keyrings/elide.gpg] https://dl.elide.dev ${channel} main`
4748
await exec.exec('sudo', ['tee', '/etc/apt/sources.list.d/elide.list'], {
4849
input: Buffer.from(sourceLine)
4950
})

src/main.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import buildOptions, {
88
ElideSetupActionOptions,
99
defaults,
1010
normalizeOs,
11-
normalizeArch
11+
normalizeArch,
12+
normalizeChannel
1213
} from './options'
1314

1415
import { downloadRelease, ElideRelease } from './releases'
@@ -137,6 +138,9 @@ export async function run(
137138
arch: normalizeArch(
138139
stringOption(OptionName.ARCH, process.arch) as string
139140
),
141+
channel: normalizeChannel(
142+
stringOption(OptionName.CHANNEL, 'nightly') as string
143+
),
140144
export_path: booleanOption(OptionName.EXPORT_PATH, true),
141145
token: stringOption(OptionName.TOKEN, process.env.GITHUB_TOKEN),
142146
custom_url: stringOption(OptionName.CUSTOM_URL),

src/options.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import path from 'node:path'
66
*/
77
export enum OptionName {
88
VERSION = 'version',
9+
CHANNEL = 'channel',
910
OS = 'os',
1011
ARCH = 'arch',
1112
EXPORT_PATH = 'export_path',
@@ -20,10 +21,15 @@ export enum OptionName {
2021
* Describes the interface provided by setup action configuration, once interpreted and once
2122
* defaults are applied.
2223
*/
24+
export type ElideChannel = 'nightly' | 'preview' | 'release'
25+
2326
export interface ElideSetupActionOptions {
2427
// Desired version of Elide; the special token `latest` resolves the latest version.
2528
version: string | 'latest'
2629

30+
// Release channel: 'nightly' (default), 'preview', or 'release'.
31+
channel: ElideChannel
32+
2733
// Whether to setup Elide on the PATH; defaults to `true`.
2834
export_path: boolean
2935

@@ -79,6 +85,7 @@ const defaultTargetPath =
7985
*/
8086
export const defaults: ElideSetupActionOptions = {
8187
version: 'latest',
88+
channel: 'nightly',
8289
no_cache: false,
8390
export_path: true,
8491
force: false,
@@ -88,6 +95,25 @@ export const defaults: ElideSetupActionOptions = {
8895
install_path: defaultTargetPath
8996
}
9097

98+
/**
99+
* Normalize a channel string to a recognized channel token.
100+
*/
101+
export function normalizeChannel(
102+
channel: string
103+
): ElideChannel {
104+
switch (channel.trim().toLowerCase()) {
105+
case 'nightly':
106+
return 'nightly'
107+
case 'preview':
108+
return 'preview'
109+
case 'release':
110+
case 'stable':
111+
return 'release'
112+
default:
113+
return 'nightly'
114+
}
115+
}
116+
91117
/**
92118
* Normalize the provided OS name or token into a recognized token.
93119
*

src/releases.ts

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -137,22 +137,16 @@ export async function buildDownloadUrl(
137137
archiveType = ArchiveType.TXZ
138138
}
139139

140-
// determine channel and revision from version tag
141-
// tag_name examples: "nightly-20260323", "preview-20260323", "1.0.0"
142-
let channel = 'release'
143-
let revision = version.tag_name
144-
if (version.tag_name.startsWith('nightly-')) {
145-
channel = 'nightly'
146-
revision = version.tag_name.slice('nightly-'.length)
147-
} else if (version.tag_name.startsWith('preview-')) {
148-
channel = 'preview'
149-
revision = version.tag_name.slice('preview-'.length)
150-
}
140+
// Use the explicit channel from options; fall back to inferring from tag
141+
const channel = options.channel || 'nightly'
151142

152-
// when version was resolved (not user-provided), use "latest" to let
153-
// the CDN resolve the current artifact
143+
// Determine revision: use "latest" when version is "latest",
144+
// otherwise use the version as-is (a semver like "1.0.0")
145+
let revision: string
154146
if (options.version === 'latest') {
155147
revision = 'latest'
148+
} else {
149+
revision = options.version
156150
}
157151

158152
// Map internal tokens to CDN platform tags (darwin→macos, aarch64→arm64)

0 commit comments

Comments
 (0)