react-native-cache-build-gitlab 1.0.6 โ 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +98 -70
- package/package.json +4 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/provider-gitlab/artifacts.d.ts +0 -19
- package/dist/provider-gitlab/artifacts.js +0 -106
- package/dist/provider-gitlab/config.d.ts +0 -8
- package/dist/provider-gitlab/config.js +0 -21
- package/dist/provider-gitlab/providerGitlab.d.ts +0 -36
- package/dist/provider-gitlab/providerGitlab.js +0 -78
package/README.md
CHANGED
|
@@ -4,14 +4,13 @@ GitLab Generic Package provider for [RockJS](https://rockjs.dev) with single pac
|
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
๐ฆ **Single Package Storage**:
|
|
7
|
+
๐ฆ **Single Package Storage**: Stores all native builds (iOS & Android) in a single GitLab Generic Package.
|
|
8
8
|
|
|
9
9
|
๐งพ **Fingerprint-based Lookup**: Fast artifact retrieval by filename matching.
|
|
10
10
|
|
|
11
11
|
๐ค๏ธ **CI/CD Ready**: Works seamlessly with GitLab CI.
|
|
12
12
|
|
|
13
|
-
๐ช **Cost Effective**: Reduces package registry clutter.
|
|
14
|
-
|
|
13
|
+
๐ช **Cost Effective**: Reduces package registry clutter by grouping artifacts.
|
|
15
14
|
|
|
16
15
|
## Installation
|
|
17
16
|
|
|
@@ -21,99 +20,100 @@ npm install react-native-cache-build-gitlab
|
|
|
21
20
|
yarn add react-native-cache-build-gitlab
|
|
22
21
|
```
|
|
23
22
|
|
|
24
|
-
## โ ๏ธ
|
|
25
|
-
|
|
23
|
+
## โ ๏ธ Prerequisites & Configuration
|
|
24
|
+
|
|
25
|
+
**Important:** You must configure your project according to the [RockJS documentation](https://www.rockjs.dev/docs/cli/migrating-from-community-cli).
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
Before using this provider, you need to set up authentication. This provider uses `CI_JOB_TOKEN` as the default environment variable for authentication.
|
|
28
28
|
|
|
29
|
-
Create a GitLab Personal Access Token (PAT) and expose it locally as the environment variable **CI_JOB_TOKEN**.
|
|
30
29
|
### **1. Create a Personal Access Token**
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
30
|
+
|
|
31
|
+
- Go to **GitLab** โ **Edit profile** โ **Personal access tokens**.
|
|
32
|
+
- Click **Add new token**.
|
|
33
|
+
- Give the token a name and expiration date (recommended).
|
|
34
|
+
- Select scopes you need (commonly: `read_api`, `read_repository`, `write_repository`).
|
|
35
|
+
- Create the token and copy it now โ GitLab shows it only once.
|
|
36
36
|
|
|
37
37
|

|
|
38
38
|
|
|
39
39
|
### **2. Expose the token as an environment variable**
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
The provider expects the token in the `CI_JOB_TOKEN` environment variable
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
export CI_JOB_TOKEN=glt-abc123...
|
|
46
|
-
````
|
|
43
|
+
#### Temporary (Current Shell)
|
|
47
44
|
|
|
48
|
-
### Persist permanently (macOS with Zsh)
|
|
49
|
-
* Open your Zsh config:
|
|
50
|
-
```bash
|
|
51
|
-
nano ~/.zshrc
|
|
52
|
-
```
|
|
53
|
-
* Add the line:
|
|
54
45
|
```bash
|
|
55
46
|
export CI_JOB_TOKEN=glt-abc123...
|
|
56
47
|
```
|
|
57
|
-
|
|
48
|
+
|
|
49
|
+
#### Permanent (macOS/Linux - Zsh):
|
|
50
|
+
|
|
58
51
|
```bash
|
|
52
|
+
echo 'export CI_JOB_TOKEN=glt-abc123...' >> ~/.zshrc
|
|
59
53
|
source ~/.zshrc
|
|
60
54
|
```
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
echo $CI_JOB_TOKEN
|
|
64
|
-
```
|
|
55
|
+
|
|
56
|
+
**Note:** In GitLab CI pipelines, `CI_JOB_TOKEN` is automatically injected, so you don't need to configure it manually there.
|
|
65
57
|
|
|
66
58
|
## Usage
|
|
67
59
|
|
|
68
60
|
In your `rock.config.mjs`:
|
|
69
61
|
|
|
70
62
|
```ts
|
|
71
|
-
import {platformIOS} from "@rock-js/platform-ios";
|
|
72
|
-
import {platformAndroid} from "@rock-js/platform-android";
|
|
73
|
-
import {providerGitLab} from "react-native-cache-build-gitlab";
|
|
74
|
-
import {pluginMetro} from "@rock-js/plugin-metro";
|
|
63
|
+
import { platformIOS } from "@rock-js/platform-ios";
|
|
64
|
+
import { platformAndroid } from "@rock-js/platform-android";
|
|
65
|
+
import { providerGitLab } from "react-native-cache-build-gitlab";
|
|
66
|
+
import { pluginMetro } from "@rock-js/plugin-metro";
|
|
75
67
|
|
|
76
68
|
export default {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
69
|
+
bundler: pluginMetro(),
|
|
70
|
+
platforms: {
|
|
71
|
+
ios: platformIOS(),
|
|
72
|
+
android: platformAndroid(),
|
|
73
|
+
},
|
|
74
|
+
remoteCacheProvider: providerGitLab({
|
|
75
|
+
packageName: "mobile-artifacts",
|
|
76
|
+
registryServer: "https://your-gitlab-instance.com",
|
|
77
|
+
projectId: 1234,
|
|
78
|
+
/*
|
|
79
|
+
* token: process.env.CI_JOB_TOKEN (default)
|
|
80
|
+
* tokenHeader: process.env.CI ? "JOB-TOKEN" : "PRIVATE-TOKEN" (default)
|
|
81
|
+
* */
|
|
82
|
+
}),
|
|
83
|
+
fingerprint: {
|
|
84
|
+
ignorePaths: [
|
|
85
|
+
"ios/Podfile.lock",
|
|
86
|
+
"ios/**/xcuserdata",
|
|
87
|
+
"ios/**/project.pbxproj",
|
|
88
|
+
// Add more paths to ignore as needed
|
|
89
|
+
],
|
|
90
|
+
},
|
|
99
91
|
};
|
|
100
92
|
```
|
|
101
93
|
|
|
102
94
|
## Configuration
|
|
103
95
|
|
|
104
|
-
| Option
|
|
105
|
-
|
|
|
106
|
-
| `packageName`
|
|
107
|
-
| `registryServer`
|
|
108
|
-
| `projectId`
|
|
96
|
+
| Option | Type | Description |
|
|
97
|
+
| ---------------- | -------- | ------------------------------------------------------------------------------------------ |
|
|
98
|
+
| `packageName` | `string` | Package name in GitLab Generic Package Registry |
|
|
99
|
+
| `registryServer` | `string` | GitLab instance URL |
|
|
100
|
+
| `projectId` | `number` | GitLab project ID |
|
|
101
|
+
| `token` | `string` | (Optional) Auth token. Defaults to `process.env.CI_JOB_TOKEN` |
|
|
102
|
+
| `tokenHeader` | `string` | (Optional) Auth token header. Defaults to `process.env.CI ? "JOB-TOKEN" : "PRIVATE-TOKEN"` |
|
|
109
103
|
|
|
110
104
|
## How It Works
|
|
111
105
|
|
|
112
106
|
### Upload (CI)
|
|
113
107
|
|
|
114
|
-
|
|
108
|
+
When your CI pipeline runs, you can use a script to upload the build artifacts to the GitLab Package Registry. (See the `example` folder in the repository for the `upload-cache-remote.sh` script).
|
|
115
109
|
|
|
116
|
-
|
|
110
|
+

|
|
111
|
+
|
|
112
|
+
### Registry Structure
|
|
113
|
+
|
|
114
|
+
All builds are uploaded to a single package version (e.g., 1.0.0).
|
|
115
|
+
|
|
116
|
+

|
|
117
117
|
|
|
118
118
|
```
|
|
119
119
|
mobile-artifacts@1.0.0/
|
|
@@ -122,13 +122,19 @@ mobile-artifacts@1.0.0/
|
|
|
122
122
|
โโโ ...
|
|
123
123
|
```
|
|
124
124
|
|
|
125
|
-
### Download (Local
|
|
125
|
+
### Download (Local)
|
|
126
126
|
|
|
127
|
-
When
|
|
127
|
+
When you run `bun rock:run-ios` or `bun rock:run-android`:
|
|
128
128
|
|
|
129
|
-
1.
|
|
130
|
-
2.
|
|
131
|
-
3.
|
|
129
|
+
1. Rock calculates the **project fingerprint**.
|
|
130
|
+
2. The provider searches the GitLab Package for a file containing that fingerprint.
|
|
131
|
+
3. If found, it downloads and extracts the artifact automatically.
|
|
132
|
+
|
|
133
|
+
> Android:
|
|
134
|
+
> 
|
|
135
|
+
|
|
136
|
+
> iOS:
|
|
137
|
+
> 
|
|
132
138
|
|
|
133
139
|
## GitLab CI Example
|
|
134
140
|
|
|
@@ -136,11 +142,33 @@ When running:
|
|
|
136
142
|
build_android_cache:
|
|
137
143
|
stage: build
|
|
138
144
|
script:
|
|
139
|
-
-
|
|
140
|
-
|
|
141
|
-
|
|
145
|
+
- |
|
|
146
|
+
bun run rock:build-android
|
|
147
|
+
|
|
148
|
+
CACHE_DIR="$(ls -1dt .rock/cache/remote-build/${NAME_PREFIX}-* | head -n1 || true)"
|
|
149
|
+
|
|
150
|
+
if [[ -z "${CACHE_DIR}" || ! -d "${CACHE_DIR}" ]]; then
|
|
151
|
+
echo "No cache output under .rock/cache/remote-build/${NAME_PREFIX}-*"
|
|
152
|
+
exit 1
|
|
153
|
+
fi
|
|
154
|
+
echo "CACHE_DIR=${CACHE_DIR}"
|
|
155
|
+
|
|
156
|
+
FP="${CACHE_DIR##*-}"
|
|
157
|
+
echo "Fingerprint: ${FP}"
|
|
158
|
+
|
|
159
|
+
if ! compgen -G "${CACHE_DIR}"/*.apk > /dev/null; then
|
|
160
|
+
echo "No .apk found in ${CACHE_DIR}"
|
|
161
|
+
ls -la "${CACHE_DIR}" || true
|
|
162
|
+
exit 1
|
|
163
|
+
fi
|
|
164
|
+
|
|
165
|
+
FILE_UPLOAD_NAME="${NAME_PREFIX}-${FP}.zip"
|
|
166
|
+
echo "FILE_UPLOAD_NAME=${FILE_UPLOAD_NAME}"
|
|
167
|
+
|
|
168
|
+
sh scripts/upload-cache-remote.sh "${CACHE_DIR}" "${FILE_UPLOAD_NAME}" android
|
|
142
169
|
```
|
|
143
|
-
|
|
170
|
+
|
|
171
|
+
> **_You can refer to the CI gitlab config in folder example_**
|
|
144
172
|
|
|
145
173
|
## License
|
|
146
174
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-cache-build-gitlab",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -15,6 +15,9 @@
|
|
|
15
15
|
},
|
|
16
16
|
"author": "Nguyแป
n Cรดng Tuแบฅn",
|
|
17
17
|
"homepage": "https://github.com/congtuandevmobile",
|
|
18
|
+
"repository": {
|
|
19
|
+
"url": "https://github.com/congtuandevmobile/react-native-cache-build-gitlab"
|
|
20
|
+
},
|
|
18
21
|
"license": "MIT",
|
|
19
22
|
"devDependencies": {
|
|
20
23
|
"@types/bun": "latest",
|
package/dist/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { providerGitLab } from "./provider-gitlab/providerGitlab.js";
|
package/dist/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { providerGitLab } from "./provider-gitlab/providerGitlab.js";
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { type RemoteArtifact } from "@rock-js/tools";
|
|
2
|
-
export type GitLabRepoDetails = {
|
|
3
|
-
registryServer: string;
|
|
4
|
-
projectId: number | string;
|
|
5
|
-
token: string;
|
|
6
|
-
tokenHeader: "PRIVATE-TOKEN" | "JOB-TOKEN";
|
|
7
|
-
packageName: string;
|
|
8
|
-
};
|
|
9
|
-
export type GitLabArtifact = {
|
|
10
|
-
packageId: number;
|
|
11
|
-
fileId: number;
|
|
12
|
-
name: string;
|
|
13
|
-
version: string;
|
|
14
|
-
sizeInBytes: number;
|
|
15
|
-
createdAt: string;
|
|
16
|
-
downloadUrl: string;
|
|
17
|
-
};
|
|
18
|
-
export declare function fetchGitLabArtifactsByName(name: string | undefined, repo: GitLabRepoDetails, limit?: number, version?: string): Promise<GitLabArtifact[]>;
|
|
19
|
-
export declare function deleteGitLabArtifacts(artifacts: GitLabArtifact[], repo: GitLabRepoDetails, artifactNameForLog?: string): Promise<RemoteArtifact[]>;
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import { cacheManager, color, colorLink, logger, RockError, } from "@rock-js/tools";
|
|
2
|
-
const PAGE_SIZE = 100;
|
|
3
|
-
function headersFor(repo) {
|
|
4
|
-
return {
|
|
5
|
-
[repo.tokenHeader]: repo.token,
|
|
6
|
-
Accept: "application/json",
|
|
7
|
-
};
|
|
8
|
-
}
|
|
9
|
-
async function httpJson(url, repo) {
|
|
10
|
-
const res = await fetch(url, { headers: headersFor(repo) });
|
|
11
|
-
if (!res.ok) {
|
|
12
|
-
const body = await res.text().catch(() => "");
|
|
13
|
-
const info = `${res.status} ${res.statusText}${body ? ` โ ${body}` : ""}`;
|
|
14
|
-
if (res.status === 401 || res.status === 403) {
|
|
15
|
-
cacheManager.remove("gitlabToken");
|
|
16
|
-
throw new RockError(`GitLab auth failed.\nUpdate token under ${color.bold("remoteCacheProvider")} in ${colorLink("rock.config.mjs")}. Local uses ${color.bold("PRIVATE-TOKEN")}, CI uses ${color.bold("JOB-TOKEN")}.\nURL: ${colorLink(url)}\nError: ${info}`);
|
|
17
|
-
}
|
|
18
|
-
if (res.status === 404) {
|
|
19
|
-
throw new RockError(`GitLab 404.\nCheck registryServer/projectId/packageName or token perms.\nURL: ${colorLink(url)}`);
|
|
20
|
-
}
|
|
21
|
-
throw new RockError(`GitLab request failed: ${info}`);
|
|
22
|
-
}
|
|
23
|
-
return (await res.json());
|
|
24
|
-
}
|
|
25
|
-
function genericDownloadUrl(repo, packageName, version, fileName) {
|
|
26
|
-
const { registryServer, projectId } = repo;
|
|
27
|
-
return `${registryServer}/api/v4/projects/${encodeURIComponent(String(projectId))}/packages/generic/${encodeURIComponent(packageName)}/${encodeURIComponent(version)}/${encodeURIComponent(fileName)}`;
|
|
28
|
-
}
|
|
29
|
-
export async function fetchGitLabArtifactsByName(name, repo, limit, version) {
|
|
30
|
-
if (!repo?.token) {
|
|
31
|
-
throw new RockError("Missing GitLab token. Valid repoDetails.token & tokenHeader pass.");
|
|
32
|
-
}
|
|
33
|
-
const perPage = Math.min(limit ?? PAGE_SIZE, PAGE_SIZE);
|
|
34
|
-
let page = 1;
|
|
35
|
-
const packages = [];
|
|
36
|
-
while (true) {
|
|
37
|
-
const url = `${repo.registryServer}/api/v4/projects/${encodeURIComponent(String(repo.projectId))}/packages` +
|
|
38
|
-
`?package_type=generic&per_page=${perPage}&page=${page}` +
|
|
39
|
-
(name ? `&package_name=${encodeURIComponent(name)}` : "");
|
|
40
|
-
const chunk = await httpJson(url, repo);
|
|
41
|
-
if (!chunk.length)
|
|
42
|
-
break;
|
|
43
|
-
packages.push(...chunk);
|
|
44
|
-
if (chunk.length < perPage)
|
|
45
|
-
break;
|
|
46
|
-
page += 1;
|
|
47
|
-
}
|
|
48
|
-
const artifacts = [];
|
|
49
|
-
for (const pkg of packages) {
|
|
50
|
-
if (pkg.package_type !== "generic" || !pkg.version)
|
|
51
|
-
continue;
|
|
52
|
-
// Don't filter by version here - we'll filter by filename later
|
|
53
|
-
let fPage = 1;
|
|
54
|
-
while (true) {
|
|
55
|
-
const filesUrl = `${repo.registryServer}/api/v4/projects/${encodeURIComponent(String(repo.projectId))}` +
|
|
56
|
-
`/packages/${pkg.id}/package_files?per_page=${PAGE_SIZE}&page=${fPage}`;
|
|
57
|
-
const files = await httpJson(filesUrl, repo);
|
|
58
|
-
if (!files.length)
|
|
59
|
-
break;
|
|
60
|
-
for (const file of files) {
|
|
61
|
-
// If version (fingerprint) is provided, filter by filename containing it
|
|
62
|
-
if (version && !file.file_name.includes(version))
|
|
63
|
-
continue;
|
|
64
|
-
artifacts.push({
|
|
65
|
-
packageId: pkg.id,
|
|
66
|
-
fileId: file.id,
|
|
67
|
-
name: pkg.name,
|
|
68
|
-
version: pkg.version,
|
|
69
|
-
sizeInBytes: file.size,
|
|
70
|
-
createdAt: file.created_at,
|
|
71
|
-
downloadUrl: genericDownloadUrl(repo, pkg.name, pkg.version, file.file_name),
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
if (files.length < PAGE_SIZE)
|
|
75
|
-
break;
|
|
76
|
-
fPage += 1;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
artifacts.sort((a, b) => b.createdAt.localeCompare(a.createdAt));
|
|
80
|
-
return artifacts;
|
|
81
|
-
}
|
|
82
|
-
export async function deleteGitLabArtifacts(artifacts, repo, artifactNameForLog) {
|
|
83
|
-
const deleted = [];
|
|
84
|
-
try {
|
|
85
|
-
for (const artifact of artifacts) {
|
|
86
|
-
const url = `${repo.registryServer}/api/v4/projects/${encodeURIComponent(String(repo.projectId))}/packages/${artifact.packageId}/package_files/${artifact.fileId}`;
|
|
87
|
-
const res = await fetch(url, {
|
|
88
|
-
method: "DELETE",
|
|
89
|
-
headers: headersFor(repo),
|
|
90
|
-
});
|
|
91
|
-
if (!res.ok) {
|
|
92
|
-
logger.warn(`Delete failed packageId=${artifact.packageId}, fileId=${artifact.fileId}: ${res.status} ${res.statusText}`);
|
|
93
|
-
continue;
|
|
94
|
-
}
|
|
95
|
-
deleted.push({
|
|
96
|
-
name: `${artifact.name}@${artifact.version}`,
|
|
97
|
-
url: artifact.downloadUrl,
|
|
98
|
-
id: String(artifact.fileId),
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
return deleted;
|
|
102
|
-
}
|
|
103
|
-
catch (error) {
|
|
104
|
-
throw new RockError(`Failed to delete GitLab artifacts${artifactNameForLog ? ` for "${artifactNameForLog}"` : ""}`, { cause: error });
|
|
105
|
-
}
|
|
106
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { GitLabRepoDetails } from "./artifacts";
|
|
2
|
-
export type DetectGitLabRepoInput = Partial<GitLabRepoDetails> & {
|
|
3
|
-
registryServer?: string;
|
|
4
|
-
projectId?: number | string;
|
|
5
|
-
token?: string;
|
|
6
|
-
tokenHeader?: "JOB-TOKEN" | "PRIVATE-TOKEN";
|
|
7
|
-
};
|
|
8
|
-
export declare function detectGitLabRepoDetails(override?: DetectGitLabRepoInput): Promise<GitLabRepoDetails>;
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { RockError } from "@rock-js/tools";
|
|
2
|
-
export async function detectGitLabRepoDetails(override) {
|
|
3
|
-
const registryServer = override?.registryServer;
|
|
4
|
-
const projectId = override?.projectId;
|
|
5
|
-
const token = override?.token;
|
|
6
|
-
const tokenHeader = override?.tokenHeader;
|
|
7
|
-
const packageName = override?.packageName;
|
|
8
|
-
if (!projectId) {
|
|
9
|
-
throw new RockError("Missing GitLab projectId. Set GITLAB_PROJECT_ID or pass in override.");
|
|
10
|
-
}
|
|
11
|
-
if (!token) {
|
|
12
|
-
throw new RockError("Missing GitLab token. Use CI_JOB_TOKEN or GITLAB_TOKEN.");
|
|
13
|
-
}
|
|
14
|
-
return {
|
|
15
|
-
registryServer,
|
|
16
|
-
projectId,
|
|
17
|
-
token,
|
|
18
|
-
tokenHeader,
|
|
19
|
-
packageName,
|
|
20
|
-
};
|
|
21
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import type { RemoteArtifact, RemoteBuildCache } from "@rock-js/tools";
|
|
2
|
-
import { type GitLabRepoDetails } from "./artifacts.js";
|
|
3
|
-
export declare class GitLabBuildCache implements RemoteBuildCache {
|
|
4
|
-
name: string;
|
|
5
|
-
repoDetails: GitLabRepoDetails | null;
|
|
6
|
-
constructor(config?: {
|
|
7
|
-
registryServer: string;
|
|
8
|
-
projectId: number | string;
|
|
9
|
-
token?: string;
|
|
10
|
-
tokenHeader?: "JOB-TOKEN" | "PRIVATE-TOKEN";
|
|
11
|
-
packageName: string;
|
|
12
|
-
});
|
|
13
|
-
getRepoDetails(): Promise<GitLabRepoDetails>;
|
|
14
|
-
list({ artifactName, limit, }: {
|
|
15
|
-
artifactName?: string;
|
|
16
|
-
limit?: number;
|
|
17
|
-
}): Promise<RemoteArtifact[]>;
|
|
18
|
-
download({ artifactName, }: {
|
|
19
|
-
artifactName: string;
|
|
20
|
-
}): Promise<Response>;
|
|
21
|
-
delete({ artifactName, limit, skipLatest, }: {
|
|
22
|
-
artifactName: string;
|
|
23
|
-
limit?: number;
|
|
24
|
-
skipLatest?: boolean;
|
|
25
|
-
}): Promise<RemoteArtifact[]>;
|
|
26
|
-
upload(): Promise<RemoteArtifact & {
|
|
27
|
-
getResponse: (buffer: Buffer | ((registryServer: string) => Buffer), contentType?: string | undefined) => Response;
|
|
28
|
-
}>;
|
|
29
|
-
}
|
|
30
|
-
export declare const providerGitLab: (options?: {
|
|
31
|
-
registryServer: string;
|
|
32
|
-
projectId: number;
|
|
33
|
-
token?: string;
|
|
34
|
-
tokenHeader?: "PRIVATE-TOKEN" | "JOB-TOKEN";
|
|
35
|
-
packageName: string;
|
|
36
|
-
}) => () => RemoteBuildCache;
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { deleteGitLabArtifacts, fetchGitLabArtifactsByName, } from "./artifacts.js";
|
|
2
|
-
import { detectGitLabRepoDetails } from "./config.js";
|
|
3
|
-
function parseRockArtifact(artifactName) {
|
|
4
|
-
if (!artifactName)
|
|
5
|
-
return {};
|
|
6
|
-
const maybe = artifactName.split("-").pop();
|
|
7
|
-
if (/^[a-f0-9]{40}$/.test(maybe))
|
|
8
|
-
return { fingerprint: maybe };
|
|
9
|
-
return {};
|
|
10
|
-
}
|
|
11
|
-
export class GitLabBuildCache {
|
|
12
|
-
name = "GitLab";
|
|
13
|
-
repoDetails = null;
|
|
14
|
-
constructor(config) {
|
|
15
|
-
if (config) {
|
|
16
|
-
const token = config.token ?? process.env.CI_JOB_TOKEN;
|
|
17
|
-
const tokenHeader = config.tokenHeader ?? (process.env.CI ? "JOB-TOKEN" : "PRIVATE-TOKEN");
|
|
18
|
-
if (!token) {
|
|
19
|
-
throw new Error("GitLab token is required. Set CI_JOB_TOKEN (CI) or GITLAB_PRIVATE_TOKEN/PRIVATE_TOKEN (local).");
|
|
20
|
-
}
|
|
21
|
-
this.repoDetails = {
|
|
22
|
-
packageName: config.packageName,
|
|
23
|
-
registryServer: config.registryServer,
|
|
24
|
-
projectId: config.projectId,
|
|
25
|
-
token,
|
|
26
|
-
tokenHeader,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
async getRepoDetails() {
|
|
31
|
-
if (!this.repoDetails) {
|
|
32
|
-
this.repoDetails = await detectGitLabRepoDetails();
|
|
33
|
-
}
|
|
34
|
-
return this.repoDetails;
|
|
35
|
-
}
|
|
36
|
-
async list({ artifactName, limit, }) {
|
|
37
|
-
const repo = await this.getRepoDetails();
|
|
38
|
-
const { fingerprint } = parseRockArtifact(artifactName);
|
|
39
|
-
const artifacts = await fetchGitLabArtifactsByName(repo.packageName, repo, limit, fingerprint);
|
|
40
|
-
return artifacts.map((artifact) => ({
|
|
41
|
-
name: `${artifact.name}@${artifact.version}`,
|
|
42
|
-
url: artifact.downloadUrl,
|
|
43
|
-
id: `${artifact.packageId}:${artifact.fileId}`,
|
|
44
|
-
}));
|
|
45
|
-
}
|
|
46
|
-
async download({ artifactName, }) {
|
|
47
|
-
const repo = await this.getRepoDetails();
|
|
48
|
-
const { fingerprint } = parseRockArtifact(artifactName);
|
|
49
|
-
if (!fingerprint)
|
|
50
|
-
throw new Error("artifactName is required");
|
|
51
|
-
const list = await fetchGitLabArtifactsByName(repo.packageName, repo, 1, fingerprint);
|
|
52
|
-
if (list.length === 0) {
|
|
53
|
-
throw new Error(`No GitLab artifact found for "${artifactName}"${fingerprint ? ` (version=${fingerprint})` : ""}`);
|
|
54
|
-
}
|
|
55
|
-
const url = list[0].downloadUrl;
|
|
56
|
-
return fetch(url, {
|
|
57
|
-
headers: {
|
|
58
|
-
[repo.tokenHeader]: repo.token,
|
|
59
|
-
"Accept-Encoding": "identity",
|
|
60
|
-
},
|
|
61
|
-
redirect: "follow",
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
async delete({ artifactName, limit, skipLatest, }) {
|
|
65
|
-
const repo = await this.getRepoDetails();
|
|
66
|
-
const { fingerprint } = parseRockArtifact(artifactName);
|
|
67
|
-
const artifacts = await fetchGitLabArtifactsByName(repo.packageName, repo, limit, fingerprint);
|
|
68
|
-
if (artifacts.length === 0) {
|
|
69
|
-
throw new Error(`No GitLab artifact found for "${artifactName}"${fingerprint ? ` (version=${fingerprint})` : ""}`);
|
|
70
|
-
}
|
|
71
|
-
const list = skipLatest ? artifacts.slice(1) : artifacts;
|
|
72
|
-
return deleteGitLabArtifacts(list, repo, artifactName);
|
|
73
|
-
}
|
|
74
|
-
async upload() {
|
|
75
|
-
throw new Error("Uploading via RemoteBuildCache is not yet implemented.");
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
export const providerGitLab = (options) => () => new GitLabBuildCache(options);
|