-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathlib.ts
More file actions
139 lines (112 loc) · 5.14 KB
/
lib.ts
File metadata and controls
139 lines (112 loc) · 5.14 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
import * as core from '@actions/core';
import { execFile } from 'node:child_process';
import { promisify } from 'node:util';
import axios, { AxiosResponse } from 'axios';
const execFileAsync = promisify(execFile);
const MAX_ATTEMPTS = 3;
const WAITING_TIME_MS = 5000;
const VERSION_REGEX = '^v[0-9]*\\.[0-9]*\\.[0-9]*$';
interface GitHubRelease {
tag_name: string;
}
async function fetchLatestVersion(): Promise<string> {
const headers = {
'Accept': 'application/vnd.github+json',
'X-GitHub-Api-Version': '2022-11-28'
};
core.info(`🔁 Attempting to get the latest DuckDB version (max attempts: ${MAX_ATTEMPTS})`);
for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
core.info(`🔁 Attempt ${attempt}/${MAX_ATTEMPTS} to get the latest DuckDB version...`);
try {
core.info(`🔍 Attempting to fetch latest DuckDB version from GitHub API...`);
const response: AxiosResponse<GitHubRelease> = await axios.get(
'https://api.github.com/repos/duckdb/duckdb/releases/latest',
{ headers }
);
if (response.status === 200) {
const version = response.data.tag_name;
core.info(`ℹ️ Latest DuckDB version found is ${version}.`);
return version;
}
if (attempt < MAX_ATTEMPTS) {
core.warning(`⚠️ Failed to get latest DuckDB version (status ${response.status}), attempt ${attempt} of ${MAX_ATTEMPTS}`);
} else {
core.error(`❌ Failed to get latest DuckDB version (status ${response.status}), last attempt (${attempt})`);
}
} catch (err) {
const errorMessage = err instanceof Error ? err.message : String(err);
if (attempt < MAX_ATTEMPTS) {
core.warning(`⚠️ Attempt ${attempt} failed: ${errorMessage}`);
} else {
core.error(`❌ Attempt ${attempt} failed: ${errorMessage}`);
}
}
if (attempt < MAX_ATTEMPTS) {
core.info(`🔁 Retry attempt ${attempt + 1}...`);
await new Promise(resolve => setTimeout(resolve, WAITING_TIME_MS * attempt));
}
}
throw new Error(`Failed to get latest DuckDB version after ${MAX_ATTEMPTS} attempts.`);
}
function validateVersion(version: string): void {
const regex = new RegExp(VERSION_REGEX);
if (!regex.test(version)) {
throw new Error(`Version not valid: ${version}`);
}
}
async function installDuckDB(version: string): Promise<void> {
core.info(`📥 Installing DuckDB version: ${version}`);
const zipFile = 'duckdb_cli-linux-amd64.zip';
const url = `https://github.com/duckdb/duckdb/releases/download/${version}/${zipFile}`;
try {
// Download DuckDB CLI zip file
core.info('⬇️ Downloading DuckDB CLI...');
await execFileAsync('wget', [url]);
// Unzip the downloaded file
core.info('📦 Extracting DuckDB CLI...');
await execFileAsync('unzip', [zipFile]);
// Create directory and move binary
core.info('📂 Setting up DuckDB installation...');
await execFileAsync('mkdir', ['-p', '/opt/duckdb']);
await execFileAsync('mv', ['duckdb', '/opt/duckdb']);
await execFileAsync('chmod', ['+x', '/opt/duckdb/duckdb']);
// Create symlink (requires sudo)
core.info('🔗 Creating symlink...');
await execFileAsync('sudo', ['ln', '-s', '/opt/duckdb/duckdb', '/usr/bin/duckdb']);
// Clean up zip file
core.info('🧹 Cleaning up...');
await execFileAsync('rm', [zipFile]);
// Verify installation
core.info('✅ Verifying installation...');
const { stdout } = await execFileAsync('duckdb', ['--version']);
core.info(`✔️ DuckDB ${version} successfully installed.`);
core.info(stdout.trim());
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
core.error(`❌ ${errorMessage}`);
throw new Error(`Installation failed: ${errorMessage}`);
}
}
export default async function (): Promise<void> {
try {
const inputVersion = core.getInput('version');
core.debug(`🔍 Looking for the latest DuckDB version...`);
const latestVersion = await fetchLatestVersion();
let selectedVersion: string;
if (inputVersion === 'latest') {
core.info(`ℹ️ DuckDB latest version requested: ${latestVersion} will be installed.`);
selectedVersion = latestVersion;
} else {
selectedVersion = inputVersion;
core.info(`📦 DuckDB ${inputVersion} requested.`);
if (inputVersion !== latestVersion) {
core.warning(`🆕 DuckDB ${latestVersion} is available.`);
}
}
validateVersion(selectedVersion);
await installDuckDB(selectedVersion);
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
core.setFailed(errorMessage);
}
}