Skip to content

Commit af2634f

Browse files
authored
Merge pull request #132 from DeLaGuardo/128-leiningen-download-url-moving
Download url for leiningen
2 parents e6e77cd + 5403e90 commit af2634f

File tree

6 files changed

+459
-43
lines changed

6 files changed

+459
-43
lines changed
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
name: Test Leiningen JAR Download
2+
3+
# This workflow tests the fix for issue #128
4+
# https://github.com/DeLaGuardo/setup-clojure/issues/128
5+
#
6+
# Leiningen is moving from GitHub to Codeberg. This workflow verifies that
7+
# setup-clojure downloads the JAR directly from GitHub Releases instead of
8+
# relying on `lein self-install` (which would download from Codeberg for
9+
# newer versions).
10+
11+
permissions:
12+
contents: read
13+
14+
on:
15+
push:
16+
paths:
17+
- "src/leiningen.ts"
18+
- ".github/workflows/test-leiningen-jar-download.yml"
19+
pull_request:
20+
paths:
21+
- "src/leiningen.ts"
22+
- ".github/workflows/test-leiningen-jar-download.yml"
23+
workflow_dispatch:
24+
25+
jobs:
26+
test-leiningen-specific-version:
27+
strategy:
28+
matrix:
29+
os: [ubuntu-latest, macOS-latest]
30+
version: ["2.9.1", "2.10.0", "2.11.2", "2.12.0"]
31+
32+
runs-on: ${{ matrix.os }}
33+
34+
steps:
35+
- name: Checkout
36+
uses: actions/checkout@v4
37+
38+
- name: Prepare java
39+
uses: actions/setup-java@v4
40+
with:
41+
distribution: "zulu"
42+
java-version: "11"
43+
44+
- name: Install Leiningen ${{ matrix.version }}
45+
uses: ./
46+
with:
47+
lein: ${{ matrix.version }}
48+
github-token: ${{ secrets.GITHUB_TOKEN }}
49+
50+
- name: Verify lein version
51+
run: |
52+
echo "Expected version: ${{ matrix.version }}"
53+
lein version
54+
# Verify the version matches (lein version outputs: Leiningen X.Y.Z on Java ...)
55+
lein version 2>&1 | grep -q "Leiningen ${{ matrix.version }}"
56+
57+
- name: Verify LEIN_JAR is set
58+
run: |
59+
echo "LEIN_JAR=$LEIN_JAR"
60+
test -n "$LEIN_JAR" || (echo "LEIN_JAR not set" && exit 1)
61+
test -f "$LEIN_JAR" || (echo "LEIN_JAR file does not exist" && exit 1)
62+
63+
- name: Verify JAR is in self-installs directory
64+
run: |
65+
echo "LEIN_HOME=$LEIN_HOME"
66+
ls -la "$LEIN_HOME/self-installs/"
67+
test -f "$LEIN_HOME/self-installs/leiningen-${{ matrix.version }}-standalone.jar"
68+
69+
test-leiningen-latest:
70+
strategy:
71+
matrix:
72+
os: [ubuntu-latest, macOS-latest]
73+
74+
runs-on: ${{ matrix.os }}
75+
76+
steps:
77+
- name: Checkout
78+
uses: actions/checkout@v4
79+
80+
- name: Prepare java
81+
uses: actions/setup-java@v4
82+
with:
83+
distribution: "zulu"
84+
java-version: "11"
85+
86+
- name: Install Leiningen latest
87+
uses: ./
88+
with:
89+
lein: latest
90+
github-token: ${{ secrets.GITHUB_TOKEN }}
91+
92+
- name: Verify lein works
93+
run: lein version
94+
95+
- name: Verify LEIN_JAR is set
96+
run: |
97+
echo "LEIN_JAR=$LEIN_JAR"
98+
test -n "$LEIN_JAR" || (echo "LEIN_JAR not set" && exit 1)
99+
test -f "$LEIN_JAR" || (echo "LEIN_JAR file does not exist" && exit 1)
100+
101+
- name: Verify JAR is in self-installs directory
102+
run: |
103+
echo "LEIN_HOME=$LEIN_HOME"
104+
ls -la "$LEIN_HOME/self-installs/"
105+
# Should have exactly one JAR file
106+
test $(ls "$LEIN_HOME/self-installs/"*.jar | wc -l) -eq 1
107+
108+
test-leiningen-windows:
109+
strategy:
110+
matrix:
111+
version: ["2.11.2", "2.12.0"]
112+
113+
runs-on: windows-latest
114+
115+
steps:
116+
- name: Checkout
117+
uses: actions/checkout@v4
118+
119+
- name: Prepare java
120+
uses: actions/setup-java@v4
121+
with:
122+
distribution: "zulu"
123+
java-version: "11"
124+
125+
- name: Install Leiningen ${{ matrix.version }}
126+
uses: ./
127+
with:
128+
lein: ${{ matrix.version }}
129+
github-token: ${{ secrets.GITHUB_TOKEN }}
130+
131+
- name: Verify lein version (PowerShell)
132+
shell: powershell
133+
run: |
134+
lein version
135+
if (-not $env:LEIN_JAR) { throw "LEIN_JAR not set" }
136+
if (-not (Test-Path $env:LEIN_JAR)) { throw "LEIN_JAR file does not exist" }
137+
138+
- name: Verify lein version (cmd)
139+
shell: cmd
140+
run: lein version
141+
142+
- name: Verify JAR location (PowerShell)
143+
shell: powershell
144+
run: |
145+
Write-Host "LEIN_HOME=$env:LEIN_HOME"
146+
Get-ChildItem "$env:LEIN_HOME\self-installs"
147+
148+
test-leiningen-caching:
149+
runs-on: ubuntu-latest
150+
151+
steps:
152+
- name: Checkout
153+
uses: actions/checkout@v4
154+
155+
- name: Prepare java
156+
uses: actions/setup-java@v4
157+
with:
158+
distribution: "zulu"
159+
java-version: "11"
160+
161+
- name: Install Leiningen (first run - should download)
162+
uses: ./
163+
with:
164+
lein: "2.11.2"
165+
github-token: ${{ secrets.GITHUB_TOKEN }}
166+
167+
- name: Verify first installation
168+
run: lein version
169+
170+
- name: Install Leiningen (second run - should use cache)
171+
uses: ./
172+
with:
173+
lein: "2.11.2"
174+
github-token: ${{ secrets.GITHUB_TOKEN }}
175+
176+
- name: Verify cached installation
177+
run: lein version
178+
179+
test-leiningen-create-project:
180+
strategy:
181+
matrix:
182+
os: [ubuntu-latest, macOS-latest]
183+
184+
runs-on: ${{ matrix.os }}
185+
186+
steps:
187+
- name: Checkout
188+
uses: actions/checkout@v4
189+
190+
- name: Prepare java
191+
uses: actions/setup-java@v4
192+
with:
193+
distribution: "zulu"
194+
java-version: "11"
195+
196+
- name: Install Leiningen
197+
uses: ./
198+
with:
199+
lein: "2.12.0"
200+
github-token: ${{ secrets.GITHUB_TOKEN }}
201+
202+
- name: Create and test a new project
203+
run: |
204+
cd /tmp
205+
lein new app test-project
206+
cd test-project
207+
# Skip 'lein test' as default app template includes a failing test (FIXME)
208+
lein run

__tests__/leiningen.test.ts

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,18 @@ import {VERSION} from '../src/version'
1010
const toolPath = join(__dirname, 'runner', 'tools', 'leiningen')
1111
const tempPath = join(__dirname, 'runner', 'temp', 'leiningen')
1212
const downloadPath = join(__dirname, 'runner', 'download')
13+
const jarDownloadPath = join(__dirname, 'runner', 'download', 'leiningen.jar')
14+
const zipDownloadPath = join(__dirname, 'runner', 'download', 'leiningen.zip')
1315
const cachePath = join(__dirname, 'runner', 'cache')
1416

1517
import * as leiningen from '../src/leiningen'
1618

19+
function httpError(statusCode: number): Error & {httpStatusCode: number} {
20+
return Object.assign(new Error(`Unexpected HTTP response: ${statusCode}`), {
21+
httpStatusCode: statusCode
22+
})
23+
}
24+
1725
jest.mock('@actions/core')
1826
const core: jest.Mocked<typeof _core> = _core as never
1927

@@ -44,6 +52,7 @@ describe('leiningen tests', () => {
4452
afterEach(async () => {
4553
jest.spyOn(global.Math, 'random').mockRestore()
4654
jest.resetAllMocks()
55+
global.fetch = undefined as never
4756
delete process.env['RUNNER_TOOL_CACHE']
4857
delete process.env['RUNNER_TEMP']
4958
})
@@ -55,12 +64,21 @@ describe('leiningen tests', () => {
5564
})
5665

5766
it('Install leiningen with normal version', async () => {
67+
// First call downloads lein script, second downloads the JAR
5868
tc.downloadTool.mockResolvedValueOnce(downloadPath)
69+
tc.downloadTool.mockResolvedValueOnce(jarDownloadPath)
5970
fs.stat.mockResolvedValueOnce({isFile: () => true} as never)
6071
tc.cacheDir.mockResolvedValueOnce(cachePath)
6172

6273
await leiningen.setup('2.9.1')
6374

75+
// Verify JAR was downloaded from GitHub releases
76+
expect(tc.downloadTool).toHaveBeenCalledWith(
77+
'https://github.com/technomancy/leiningen/releases/download/2.9.1/leiningen-2.9.1-standalone.jar',
78+
expect.any(String),
79+
undefined
80+
)
81+
6482
expect(io.mkdirP).toHaveBeenNthCalledWith(
6583
1,
6684
join(tempPath, 'temp_2000000000')
@@ -69,6 +87,22 @@ describe('leiningen tests', () => {
6987
2,
7088
join(tempPath, 'temp_2000000000', 'leiningen', 'bin')
7189
)
90+
// Verify self-installs directory was created
91+
expect(io.mkdirP).toHaveBeenNthCalledWith(
92+
3,
93+
join(tempPath, 'temp_2000000000', 'leiningen', 'self-installs')
94+
)
95+
// Verify JAR was moved to self-installs
96+
expect(io.mv).toHaveBeenCalledWith(
97+
jarDownloadPath,
98+
join(
99+
tempPath,
100+
'temp_2000000000',
101+
'leiningen',
102+
'self-installs',
103+
'leiningen-2.9.1-standalone.jar'
104+
)
105+
)
72106
expect(exec.exec.mock.calls[0]).toMatchObject([
73107
'./lein version',
74108
[],
@@ -92,12 +126,33 @@ describe('leiningen tests', () => {
92126
})
93127

94128
it('Install latest leiningen', async () => {
129+
// Mock fetch for getting latest version
130+
global.fetch = jest.fn().mockResolvedValue({
131+
ok: true,
132+
json: jest.fn().mockResolvedValue({tag_name: '2.12.0'})
133+
})
134+
135+
// First call downloads lein script, second downloads the JAR
95136
tc.downloadTool.mockResolvedValueOnce(downloadPath)
137+
tc.downloadTool.mockResolvedValueOnce(jarDownloadPath)
96138
fs.stat.mockResolvedValueOnce({isFile: () => true} as never)
97139
tc.cacheDir.mockResolvedValueOnce(cachePath)
98140

99141
await leiningen.setup('latest')
100142

143+
// Verify latest version was fetched
144+
expect(global.fetch).toHaveBeenCalledWith(
145+
'https://api.github.com/repos/technomancy/leiningen/releases/latest',
146+
expect.any(Object)
147+
)
148+
149+
// Verify JAR was downloaded with resolved version
150+
expect(tc.downloadTool).toHaveBeenCalledWith(
151+
'https://github.com/technomancy/leiningen/releases/download/2.12.0/leiningen-2.12.0-standalone.jar',
152+
expect.any(String),
153+
undefined
154+
)
155+
101156
expect(io.mkdirP).toHaveBeenNthCalledWith(
102157
1,
103158
join(tempPath, 'temp_2000000000')
@@ -128,6 +183,66 @@ describe('leiningen tests', () => {
128183
expect(core.addPath).toHaveBeenCalledWith(join(cachePath, 'bin'))
129184
})
130185

186+
it('Falls back to zip artifact when jar returns 404', async () => {
187+
tc.downloadTool.mockResolvedValueOnce(downloadPath)
188+
tc.downloadTool.mockRejectedValueOnce(httpError(404))
189+
tc.downloadTool.mockResolvedValueOnce(zipDownloadPath)
190+
fs.stat.mockResolvedValueOnce({isFile: () => true} as never)
191+
tc.cacheDir.mockResolvedValueOnce(cachePath)
192+
193+
await leiningen.setup('2.9.1')
194+
195+
expect(tc.downloadTool).toHaveBeenNthCalledWith(
196+
2,
197+
'https://github.com/technomancy/leiningen/releases/download/2.9.1/leiningen-2.9.1-standalone.jar',
198+
join(tempPath, 'leiningen-2.9.1-standalone.jar'),
199+
undefined
200+
)
201+
expect(tc.downloadTool).toHaveBeenNthCalledWith(
202+
3,
203+
'https://github.com/technomancy/leiningen/releases/download/2.9.1/leiningen-2.9.1-standalone.zip',
204+
join(tempPath, 'leiningen-2.9.1-standalone.zip'),
205+
undefined
206+
)
207+
expect(io.mv).toHaveBeenCalledWith(
208+
zipDownloadPath,
209+
join(tempPath, 'leiningen-2.9.1-standalone.jar')
210+
)
211+
expect(io.mv).toHaveBeenCalledWith(
212+
join(tempPath, 'leiningen-2.9.1-standalone.jar'),
213+
join(
214+
tempPath,
215+
'temp_2000000000',
216+
'leiningen',
217+
'self-installs',
218+
'leiningen-2.9.1-standalone.jar'
219+
)
220+
)
221+
})
222+
223+
it('Fails when both jar and zip artifacts return 404', async () => {
224+
tc.downloadTool.mockResolvedValueOnce(downloadPath)
225+
tc.downloadTool.mockRejectedValueOnce(httpError(404))
226+
tc.downloadTool.mockRejectedValueOnce(httpError(404))
227+
228+
await expect(leiningen.setup('2.9.1')).rejects.toThrow(
229+
'Unexpected HTTP response: 404'
230+
)
231+
232+
expect(tc.downloadTool).toHaveBeenNthCalledWith(
233+
2,
234+
'https://github.com/technomancy/leiningen/releases/download/2.9.1/leiningen-2.9.1-standalone.jar',
235+
join(tempPath, 'leiningen-2.9.1-standalone.jar'),
236+
undefined
237+
)
238+
expect(tc.downloadTool).toHaveBeenNthCalledWith(
239+
3,
240+
'https://github.com/technomancy/leiningen/releases/download/2.9.1/leiningen-2.9.1-standalone.zip',
241+
join(tempPath, 'leiningen-2.9.1-standalone.zip'),
242+
undefined
243+
)
244+
})
245+
131246
it('Uses version of leiningen installed in cache', async () => {
132247
tc.find.mockReturnValue(cachePath)
133248
await leiningen.setup('2.9.1')

0 commit comments

Comments
 (0)