Skip to content

Commit a447500

Browse files
committed
Download url for leiningen
1 parent 27f9157 commit a447500

6 files changed

Lines changed: 333 additions & 13 deletions

File tree

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

__tests__/leiningen.test.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ 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')
1314
const cachePath = join(__dirname, 'runner', 'cache')
1415

1516
import * as leiningen from '../src/leiningen'
@@ -55,12 +56,21 @@ describe('leiningen tests', () => {
5556
})
5657

5758
it('Install leiningen with normal version', async () => {
59+
// First call downloads lein script, second downloads the JAR
5860
tc.downloadTool.mockResolvedValueOnce(downloadPath)
61+
tc.downloadTool.mockResolvedValueOnce(jarDownloadPath)
5962
fs.stat.mockResolvedValueOnce({isFile: () => true} as never)
6063
tc.cacheDir.mockResolvedValueOnce(cachePath)
6164

6265
await leiningen.setup('2.9.1')
6366

67+
// Verify JAR was downloaded from GitHub releases
68+
expect(tc.downloadTool).toHaveBeenCalledWith(
69+
'https://github.com/technomancy/leiningen/releases/download/2.9.1/leiningen-2.9.1-standalone.jar',
70+
expect.any(String),
71+
undefined
72+
)
73+
6474
expect(io.mkdirP).toHaveBeenNthCalledWith(
6575
1,
6676
join(tempPath, 'temp_2000000000')
@@ -69,6 +79,22 @@ describe('leiningen tests', () => {
6979
2,
7080
join(tempPath, 'temp_2000000000', 'leiningen', 'bin')
7181
)
82+
// Verify self-installs directory was created
83+
expect(io.mkdirP).toHaveBeenNthCalledWith(
84+
3,
85+
join(tempPath, 'temp_2000000000', 'leiningen', 'self-installs')
86+
)
87+
// Verify JAR was moved to self-installs
88+
expect(io.mv).toHaveBeenCalledWith(
89+
jarDownloadPath,
90+
join(
91+
tempPath,
92+
'temp_2000000000',
93+
'leiningen',
94+
'self-installs',
95+
'leiningen-2.9.1-standalone.jar'
96+
)
97+
)
7298
expect(exec.exec.mock.calls[0]).toMatchObject([
7399
'./lein version',
74100
[],
@@ -92,12 +118,33 @@ describe('leiningen tests', () => {
92118
})
93119

94120
it('Install latest leiningen', async () => {
121+
// Mock fetch for getting latest version
122+
global.fetch = jest.fn().mockResolvedValue({
123+
ok: true,
124+
json: jest.fn().mockResolvedValue({tag_name: '2.12.0'})
125+
})
126+
127+
// First call downloads lein script, second downloads the JAR
95128
tc.downloadTool.mockResolvedValueOnce(downloadPath)
129+
tc.downloadTool.mockResolvedValueOnce(jarDownloadPath)
96130
fs.stat.mockResolvedValueOnce({isFile: () => true} as never)
97131
tc.cacheDir.mockResolvedValueOnce(cachePath)
98132

99133
await leiningen.setup('latest')
100134

135+
// Verify latest version was fetched
136+
expect(global.fetch).toHaveBeenCalledWith(
137+
'https://api.github.com/repos/technomancy/leiningen/releases/latest',
138+
expect.any(Object)
139+
)
140+
141+
// Verify JAR was downloaded with resolved version
142+
expect(tc.downloadTool).toHaveBeenCalledWith(
143+
'https://github.com/technomancy/leiningen/releases/download/2.12.0/leiningen-2.12.0-standalone.jar',
144+
expect.any(String),
145+
undefined
146+
)
147+
101148
expect(io.mkdirP).toHaveBeenNthCalledWith(
102149
1,
103150
join(tempPath, 'temp_2000000000')

dist/index.js

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,13 +1123,16 @@ const os = __importStar(__nccwpck_require__(857));
11231123
const fs = __importStar(__nccwpck_require__(2621));
11241124
const utils = __importStar(__nccwpck_require__(9277));
11251125
exports.identifier = 'Leiningen';
1126+
const LEIN_JAR_BASE_URL = 'https://github.com/technomancy/leiningen/releases/download';
11261127
function setup(version, githubAuth) {
11271128
return __awaiter(this, void 0, void 0, function* () {
11281129
let toolPath = tc.find(exports.identifier, utils.getCacheVersionString(version), os.arch());
11291130
if (toolPath && version !== 'latest') {
11301131
core.info(`Leiningen found in cache ${toolPath}`);
11311132
}
11321133
else {
1134+
// Resolve 'latest' to actual version number
1135+
const resolvedVersion = version === 'latest' ? yield getLatestVersion(githubAuth) : version;
11331136
const binScripts = [];
11341137
if (utils.isWindows()) {
11351138
for (const ext of ['ps1', 'bat']) {
@@ -1139,8 +1142,12 @@ function setup(version, githubAuth) {
11391142
else {
11401143
binScripts.push(yield tc.downloadTool(`https://raw.githubusercontent.com/technomancy/leiningen/${version === 'latest' ? 'stable' : version}/bin/lein`, path.join(utils.getTempDir(), 'lein'), githubAuth));
11411144
}
1145+
const jarFileName = `leiningen-${resolvedVersion}-standalone.jar`;
1146+
const jarUrl = `${LEIN_JAR_BASE_URL}/${resolvedVersion}/${jarFileName}`;
1147+
core.info(`Downloading Leiningen JAR from ${jarUrl}`);
1148+
const jarPath = yield tc.downloadTool(jarUrl, path.join(utils.getTempDir(), jarFileName), githubAuth);
11421149
const tempDir = path.join(utils.getTempDir(), `temp_${Math.floor(Math.random() * 2000000000)}`);
1143-
const leiningenDir = yield installLeiningen(binScripts, tempDir);
1150+
const leiningenDir = yield installLeiningen(binScripts, jarPath, resolvedVersion, tempDir);
11441151
core.debug(`Leiningen installed to ${leiningenDir}`);
11451152
toolPath = yield tc.cacheDir(leiningenDir, exports.identifier, utils.getCacheVersionString(version));
11461153
}
@@ -1152,14 +1159,27 @@ function setup(version, githubAuth) {
11521159
core.addPath(path.join(toolPath, 'bin'));
11531160
});
11541161
}
1155-
function installLeiningen(binScripts, destinationFolder) {
1162+
function getLatestVersion(githubAuth) {
1163+
return __awaiter(this, void 0, void 0, function* () {
1164+
const response = yield fetch('https://api.github.com/repos/technomancy/leiningen/releases/latest', {
1165+
headers: githubAuth ? { Authorization: githubAuth } : {}
1166+
});
1167+
if (!response.ok) {
1168+
throw new Error(`Failed to fetch latest Leiningen version: ${response.statusText}`);
1169+
}
1170+
const data = (yield response.json());
1171+
return data.tag_name;
1172+
});
1173+
}
1174+
function installLeiningen(binScripts, jarPath, version, destinationFolder) {
11561175
return __awaiter(this, void 0, void 0, function* () {
11571176
yield io.mkdirP(destinationFolder);
1177+
const toolDir = path.join(destinationFolder, 'leiningen');
11581178
for (const binScript of binScripts) {
11591179
const bin = path.normalize(binScript);
11601180
const binStats = yield fs.stat(bin);
11611181
if (binStats.isFile()) {
1162-
const binDir = path.join(destinationFolder, 'leiningen', 'bin');
1182+
const binDir = path.join(toolDir, 'bin');
11631183
yield io.mkdirP(binDir);
11641184
yield io.mv(bin, path.join(binDir, `${path.basename(bin)}`));
11651185
if (!utils.isWindows()) {
@@ -1170,10 +1190,13 @@ function installLeiningen(binScripts, destinationFolder) {
11701190
throw new Error('Not a file');
11711191
}
11721192
}
1193+
const selfInstallsDir = path.join(toolDir, 'self-installs');
1194+
yield io.mkdirP(selfInstallsDir);
1195+
const jarFileName = `leiningen-${version}-standalone.jar`;
1196+
yield io.mv(jarPath, path.join(selfInstallsDir, jarFileName));
11731197
const version_cmd = utils.isWindows()
1174-
? 'powershell .\\lein.ps1 self-install'
1198+
? 'powershell .\\lein.ps1 version'
11751199
: './lein version';
1176-
const toolDir = path.join(destinationFolder, 'leiningen');
11771200
const env = {
11781201
LEIN_HOME: toolDir
11791202
};

dist/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)