zarro 1.164.0 → 1.165.2
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/gulp-tasks/modules/fetch-github-release/.editorconfig +10 -0
- package/gulp-tasks/modules/fetch-github-release/.gitattributes +1 -0
- package/gulp-tasks/modules/fetch-github-release/.github/.kodiak.toml +1 -0
- package/gulp-tasks/modules/fetch-github-release/.github/workflows/release-please.yml +26 -0
- package/gulp-tasks/modules/fetch-github-release/.github/workflows/test.yml +26 -0
- package/gulp-tasks/modules/fetch-github-release/.prettierrc.json +7 -0
- package/gulp-tasks/modules/fetch-github-release/CHANGELOG.md +8 -0
- package/gulp-tasks/modules/fetch-github-release/package-lock.json +12412 -0
- package/gulp-tasks/modules/fetch-github-release/package.json +78 -0
- package/gulp-tasks/modules/fetch-github-release/renovate.json5 +19 -0
- package/gulp-tasks/modules/fetch-github-release/src/__tests__/index.ts +51 -0
- package/gulp-tasks/modules/fetch-github-release/src/constants.ts +5 -0
- package/gulp-tasks/modules/fetch-github-release/src/fetchRelease.ts +159 -0
- package/gulp-tasks/modules/fetch-github-release/src/getAssetDefault.ts +48 -0
- package/gulp-tasks/modules/fetch-github-release/src/index.ts +2 -0
- package/gulp-tasks/modules/fetch-github-release/src/isUpdateAvailable.ts +143 -0
- package/gulp-tasks/modules/fetch-github-release/src/types.ts +17 -0
- package/gulp-tasks/modules/fetch-github-release/src/util.ts +24 -0
- package/gulp-tasks/modules/increment-version.js +12 -3
- package/package.json +2 -1
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "fetch-github-release",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Fetch binary from Github releases for your platform",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git://github.com/valerybugakov/fetch-github-release.git"
|
|
8
|
+
},
|
|
9
|
+
"main": "dist/index.js",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"prepublishOnly": "npm ci && run-s build test",
|
|
12
|
+
"test": "jest",
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"build:watch": "tsc --watch",
|
|
15
|
+
"format": "run-s format:fix:*",
|
|
16
|
+
"format:ci": "run-s format:check:*",
|
|
17
|
+
"format:check:lint": "cross-env eslint $npm_package_config_eslint",
|
|
18
|
+
"format:fix:lint": "cross-env eslint --fix $npm_package_config_eslint",
|
|
19
|
+
"format:check:prettier": "cross-env prettier --check $npm_package_config_prettier",
|
|
20
|
+
"format:fix:prettier": "cross-env prettier --write $npm_package_config_prettier",
|
|
21
|
+
"prepare": "husky install"
|
|
22
|
+
},
|
|
23
|
+
"config": {
|
|
24
|
+
"eslint": "--ignore-path .gitignore --cache --format=codeframe --max-warnings=0 src/**/*.{ts,js,html} *.{ts,js,html} .*.{ts,js,html}",
|
|
25
|
+
"prettier": "--ignore-path .gitignore --loglevel=warn {src,tests,.github}/**/*.{ts,js,md,yml,json,html} *.{ts,js,yml,json,html} .*.{ts,js,yml,json,html} !package-lock.json"
|
|
26
|
+
},
|
|
27
|
+
"husky": {
|
|
28
|
+
"hooks": {
|
|
29
|
+
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
|
|
30
|
+
"pre-push": "npm run format"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"engines": {
|
|
34
|
+
"node": ">=10"
|
|
35
|
+
},
|
|
36
|
+
"keywords": [
|
|
37
|
+
"github",
|
|
38
|
+
"binary",
|
|
39
|
+
"release",
|
|
40
|
+
"fetch",
|
|
41
|
+
"get"
|
|
42
|
+
],
|
|
43
|
+
"author": "Valery Bugakov <skymk1@gmail.com> (https://github.com/valerybugakov/)",
|
|
44
|
+
"license": "MIT",
|
|
45
|
+
"files": [
|
|
46
|
+
"dist"
|
|
47
|
+
],
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@babel/eslint-parser": "^7.15.0",
|
|
50
|
+
"@commitlint/cli": "^17.6.7",
|
|
51
|
+
"@commitlint/config-conventional": "^17.6.7",
|
|
52
|
+
"@types/download": "^8.0.0",
|
|
53
|
+
"@types/jest": "^26.0.0",
|
|
54
|
+
"@types/node": "^14.0.0",
|
|
55
|
+
"@types/semver": "^7.0.0",
|
|
56
|
+
"@typescript-eslint/eslint-plugin": "^4.27.0",
|
|
57
|
+
"@typescript-eslint/parser": "^4.27.0",
|
|
58
|
+
"cross-env": "^7.0.3",
|
|
59
|
+
"eslint-config-prettier": "^8.3.0",
|
|
60
|
+
"eslint-plugin-import": "^2.24.1",
|
|
61
|
+
"eslint-plugin-prettier": "^3.4.1",
|
|
62
|
+
"expect-even-more-jest": "^1.18.0",
|
|
63
|
+
"filesystem-sandbox": "^1.24.0",
|
|
64
|
+
"husky": "^7.0.0",
|
|
65
|
+
"jest": "^27.0.0",
|
|
66
|
+
"npm-run-all": "^4.1.5",
|
|
67
|
+
"prettier": "^2.3.2",
|
|
68
|
+
"ts-jest": "^27.0.0",
|
|
69
|
+
"typescript": "^4.0.0"
|
|
70
|
+
},
|
|
71
|
+
"dependencies": {
|
|
72
|
+
"@octokit/rest": "^18.9.1",
|
|
73
|
+
"bent": "^7.3.12",
|
|
74
|
+
"decompress": "^4.2.1",
|
|
75
|
+
"semver": "^7.5.4",
|
|
76
|
+
"yafs": "^1.27.0"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
force: {
|
|
3
|
+
constraints: {
|
|
4
|
+
node: '< 15.0.0',
|
|
5
|
+
},
|
|
6
|
+
},
|
|
7
|
+
extends: ['config:base', 'schedule:weekly'],
|
|
8
|
+
rangeStrategy: 'update-lockfile',
|
|
9
|
+
automerge: true,
|
|
10
|
+
major: {
|
|
11
|
+
automerge: false,
|
|
12
|
+
},
|
|
13
|
+
lockFileMaintenance: {
|
|
14
|
+
enabled: true,
|
|
15
|
+
},
|
|
16
|
+
ignorePresets: [':prHourlyLimit2'],
|
|
17
|
+
semanticCommits: true,
|
|
18
|
+
dependencyDashboard: true,
|
|
19
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import "expect-even-more-jest";
|
|
2
|
+
import { newerVersion, listReleases, fetchLatestRelease } from "../"
|
|
3
|
+
import { Sandbox } from "filesystem-sandbox";
|
|
4
|
+
import { ls } from "yafs";
|
|
5
|
+
|
|
6
|
+
describe(`newerVersion`, () => {
|
|
7
|
+
it("should compare versions", () => {
|
|
8
|
+
expect(newerVersion("0.1.0", "0.0.1")).toBe(true)
|
|
9
|
+
expect(newerVersion("v0.1.0", "v0.0.1")).toBe(true)
|
|
10
|
+
expect(newerVersion("v0.0.1", "")).toBe(true)
|
|
11
|
+
|
|
12
|
+
expect(newerVersion("0.0.1", "0.0.1")).toBe(false)
|
|
13
|
+
expect(newerVersion("v0.0.1", "v0.0.1")).toBe(false)
|
|
14
|
+
expect(newerVersion("", "0.0.1")).toBe(false)
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
describe(`listReleases`, () => {
|
|
19
|
+
it(`should find releases`, async () => {
|
|
20
|
+
// Arrange
|
|
21
|
+
// Act
|
|
22
|
+
const result = await listReleases({ owner: "fluffynuts", repo: "NExpect" });
|
|
23
|
+
// Assert
|
|
24
|
+
expect(result)
|
|
25
|
+
.not.toBeEmptyArray();
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
describe(`fetchLatestRelease`, () => {
|
|
30
|
+
it(`should fetch and unpack`, async () => {
|
|
31
|
+
// Arrange
|
|
32
|
+
const
|
|
33
|
+
os = require("os"),
|
|
34
|
+
isWindows = os.platform() === "win32",
|
|
35
|
+
sandbox = await Sandbox.create();
|
|
36
|
+
// Act
|
|
37
|
+
await fetchLatestRelease({
|
|
38
|
+
destination: sandbox.path,
|
|
39
|
+
owner: "axllent",
|
|
40
|
+
repo: "mailpit"
|
|
41
|
+
});
|
|
42
|
+
// Assert
|
|
43
|
+
const contents = await ls(sandbox.path);
|
|
44
|
+
expect(contents)
|
|
45
|
+
.toContain(
|
|
46
|
+
isWindows
|
|
47
|
+
? "mailpit.exe"
|
|
48
|
+
: "mailpit"
|
|
49
|
+
);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { writeFile, rm } from "yafs";
|
|
2
|
+
import path from 'path'
|
|
3
|
+
|
|
4
|
+
import { Octokit } from '@octokit/rest'
|
|
5
|
+
import decompress from 'decompress'
|
|
6
|
+
const bent = require("bent");
|
|
7
|
+
|
|
8
|
+
import { PACKAGE_DATA_DIR } from './constants'
|
|
9
|
+
import { OctokitRelease, OctokitReleaseAssets, RepoInfo } from './types'
|
|
10
|
+
import { ensureDirExist } from './util'
|
|
11
|
+
import { getAssetDefault } from './getAssetDefault'
|
|
12
|
+
|
|
13
|
+
export interface FetchReleaseOptions extends RepoInfo {
|
|
14
|
+
getRelease: (owner: string, repo: string) => Promise<OctokitRelease>
|
|
15
|
+
getAsset?: (
|
|
16
|
+
version: string,
|
|
17
|
+
assets: OctokitReleaseAssets,
|
|
18
|
+
) => OctokitReleaseAssets[number] | undefined
|
|
19
|
+
accessToken?: string
|
|
20
|
+
destination?: string
|
|
21
|
+
shouldExtract?: boolean
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type AsyncFunction<T> = () => Promise<T>;
|
|
25
|
+
type AsyncVoidFunction = AsyncFunction<void>;
|
|
26
|
+
interface Dictionary<T> {
|
|
27
|
+
[key: string]: T;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface BentResponse {
|
|
31
|
+
statusCode: number;
|
|
32
|
+
json: AsyncFunction<any>;
|
|
33
|
+
text: AsyncFunction<string>;
|
|
34
|
+
arrayBuffer: AsyncFunction<Buffer>;
|
|
35
|
+
headers: Dictionary<string>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function determineFilenameFrom(response: BentResponse): string {
|
|
39
|
+
const contentDisposition = response.headers["content-disposition"];
|
|
40
|
+
if (!contentDisposition) {
|
|
41
|
+
// guess? shouldn't get here from GH queries...
|
|
42
|
+
return fallback();
|
|
43
|
+
}
|
|
44
|
+
const parts = contentDisposition.split(";").map(s => s.trim());
|
|
45
|
+
for (const part of parts) {
|
|
46
|
+
let match = part.match(/^filename=(?<filename>.+)/i);
|
|
47
|
+
if (match && match.groups) {
|
|
48
|
+
const filename = match.groups["filename"];
|
|
49
|
+
if (filename) {
|
|
50
|
+
return filename;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return fallback();
|
|
55
|
+
|
|
56
|
+
function fallback() {
|
|
57
|
+
console.warn(`Unable to determine filename from request, falling back on release.zip`);
|
|
58
|
+
return "release.zip";
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async function download(url: string, destination: string): Promise<string> {
|
|
63
|
+
const fetch = bent(url);
|
|
64
|
+
try {
|
|
65
|
+
const response = await fetch();
|
|
66
|
+
const data = await response.arrayBuffer();
|
|
67
|
+
const filename = determineFilenameFrom(response);
|
|
68
|
+
await writeFile(path.join(destination, filename), data);
|
|
69
|
+
return determineFilenameFrom(response);
|
|
70
|
+
} catch (e) {
|
|
71
|
+
const err = e as BentResponse;
|
|
72
|
+
if (err.statusCode === undefined) {
|
|
73
|
+
throw err;
|
|
74
|
+
}
|
|
75
|
+
if (err.statusCode === 301 || err.statusCode === 302) {
|
|
76
|
+
const next = err.headers["location"];
|
|
77
|
+
if (!next) {
|
|
78
|
+
throw new Error(`No location provided for http response ${err.statusCode}`);
|
|
79
|
+
}
|
|
80
|
+
return download(next, destination);
|
|
81
|
+
}
|
|
82
|
+
throw err;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async function fetchRelease(options: FetchReleaseOptions): Promise<string[]> {
|
|
87
|
+
const {
|
|
88
|
+
owner,
|
|
89
|
+
repo,
|
|
90
|
+
getRelease,
|
|
91
|
+
getAsset = getAssetDefault,
|
|
92
|
+
destination = PACKAGE_DATA_DIR,
|
|
93
|
+
shouldExtract = true,
|
|
94
|
+
} = options
|
|
95
|
+
|
|
96
|
+
if (!owner) {
|
|
97
|
+
throw new Error('Required "owner" option is missing')
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (!repo) {
|
|
101
|
+
throw new Error('Required "repo" option is missing')
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const {
|
|
105
|
+
data: { assets, tag_name: version },
|
|
106
|
+
} = await getRelease(owner, repo)
|
|
107
|
+
const downloadUrl = getAsset(version, assets)?.browser_download_url
|
|
108
|
+
|
|
109
|
+
if (!downloadUrl) {
|
|
110
|
+
throw new Error('Unable to find download URL')
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
await ensureDirExist(destination)
|
|
114
|
+
const filename = await download(downloadUrl, destination)
|
|
115
|
+
const downloadPath = path.join(destination, filename)
|
|
116
|
+
|
|
117
|
+
if (shouldExtract) {
|
|
118
|
+
const files = await decompress(downloadPath, destination)
|
|
119
|
+
await rm(downloadPath)
|
|
120
|
+
|
|
121
|
+
return files.map((file: decompress.File) => path.join(destination, file.path))
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return [downloadPath]
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Downloads and extract release for the specified tag from Github to the destination.
|
|
129
|
+
*
|
|
130
|
+
* await fetchLatestRelease({ owner: 'smallstep', repo: 'cli', tag: '1.0.0' })
|
|
131
|
+
*/
|
|
132
|
+
export async function fetchReleaseByTag(
|
|
133
|
+
options: Omit<FetchReleaseOptions, 'getRelease'> & { tag: string },
|
|
134
|
+
): Promise<string[]> {
|
|
135
|
+
return fetchRelease({
|
|
136
|
+
...options,
|
|
137
|
+
getRelease: (owner, repo) =>
|
|
138
|
+
new Octokit({ auth: options.accessToken }).repos.getReleaseByTag({
|
|
139
|
+
owner,
|
|
140
|
+
repo,
|
|
141
|
+
tag: options.tag,
|
|
142
|
+
}),
|
|
143
|
+
})
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Downloads and extract latest release from Github to the destination.
|
|
148
|
+
*
|
|
149
|
+
* await fetchLatestRelease({ owner: 'smallstep', repo: 'cli' })
|
|
150
|
+
*/
|
|
151
|
+
export async function fetchLatestRelease(
|
|
152
|
+
options: Omit<FetchReleaseOptions, 'getRelease'>,
|
|
153
|
+
): Promise<string[]> {
|
|
154
|
+
return fetchRelease({
|
|
155
|
+
...options,
|
|
156
|
+
getRelease: (owner, repo) =>
|
|
157
|
+
new Octokit({ auth: options.accessToken }).repos.getLatestRelease({ owner, repo }),
|
|
158
|
+
})
|
|
159
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { OctokitReleaseAssets } from './types'
|
|
2
|
+
|
|
3
|
+
interface PlatformIdentifier {
|
|
4
|
+
platform: string
|
|
5
|
+
arch: string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function getPlatformIdentifier(): PlatformIdentifier {
|
|
9
|
+
switch (process.platform) {
|
|
10
|
+
case 'win32':
|
|
11
|
+
return { platform: 'windows', arch: 'amd64' }
|
|
12
|
+
case 'linux':
|
|
13
|
+
if (process.arch === 'arm64') {
|
|
14
|
+
return { platform: 'linux', arch: 'arm64' }
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (process.arch === 'arm') {
|
|
18
|
+
return { platform: 'linux', arch: 'arm' }
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return { platform: 'linux', arch: 'amd64' }
|
|
22
|
+
case 'darwin':
|
|
23
|
+
return { platform: 'darwin', arch: 'amd64' }
|
|
24
|
+
default:
|
|
25
|
+
throw new Error('Unsupported platform')
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function getAssetDefault(
|
|
30
|
+
version: string,
|
|
31
|
+
assets: OctokitReleaseAssets,
|
|
32
|
+
): OctokitReleaseAssets[number] {
|
|
33
|
+
const { platform, arch } = getPlatformIdentifier()
|
|
34
|
+
|
|
35
|
+
const platformAssets = assets.filter((asset: { name: string }) => asset.name.includes(platform))
|
|
36
|
+
|
|
37
|
+
if (platformAssets.length === 1) {
|
|
38
|
+
return platformAssets[0]
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const archAsset = platformAssets.find((asset: { name: string }) => asset.name.includes(arch))
|
|
42
|
+
|
|
43
|
+
if (!archAsset) {
|
|
44
|
+
throw new Error(`Unable to find release for platform: ${platform} and arch: ${arch}`)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return archAsset
|
|
48
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { Octokit } from "@octokit/rest"
|
|
2
|
+
import { gt } from "semver"
|
|
3
|
+
|
|
4
|
+
import { RepoInfo } from "./types"
|
|
5
|
+
|
|
6
|
+
interface IsUpdateAvailableOptions extends RepoInfo {
|
|
7
|
+
currentVersion: string
|
|
8
|
+
accessToken?: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function isUpdateAvailable(options: IsUpdateAvailableOptions): Promise<boolean> {
|
|
12
|
+
const { repo, owner, currentVersion, accessToken } = options
|
|
13
|
+
const {
|
|
14
|
+
data: { tag_name: latestVersion },
|
|
15
|
+
} = await new Octokit({ auth: accessToken }).repos.getLatestRelease({ owner, repo })
|
|
16
|
+
|
|
17
|
+
return newerVersion(latestVersion, currentVersion)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface FetchLatestReleaseOptions extends RepoInfo {
|
|
21
|
+
accessToken?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface FetchLatestReleaseResult {
|
|
25
|
+
url: string;
|
|
26
|
+
id: number;
|
|
27
|
+
assets: any[];
|
|
28
|
+
name: string | null;
|
|
29
|
+
body?: string | null;
|
|
30
|
+
assets_url: string;
|
|
31
|
+
author: string;
|
|
32
|
+
body_html: string;
|
|
33
|
+
body_text: string;
|
|
34
|
+
created_at: string;
|
|
35
|
+
discussion_url: string;
|
|
36
|
+
draft: boolean;
|
|
37
|
+
html_url: string;
|
|
38
|
+
mentions_count: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export async function fetchLatestReleaseInfo(
|
|
42
|
+
opts: ListReleasesOptions
|
|
43
|
+
): Promise<ReleaseInfo> {
|
|
44
|
+
const { repo, owner, accessToken } = opts;
|
|
45
|
+
const result = await new Octokit({ auth: accessToken }).repos.getLatestRelease({ owner, repo });
|
|
46
|
+
return result.data as ReleaseInfo;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface ListReleasesOptions extends RepoInfo {
|
|
50
|
+
accessToken?: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface AuthorInfo {
|
|
54
|
+
login: string;
|
|
55
|
+
id: number;
|
|
56
|
+
node_id: string;
|
|
57
|
+
avatar_url: string;
|
|
58
|
+
gravatar_id: string;
|
|
59
|
+
url: string;
|
|
60
|
+
html_url: string;
|
|
61
|
+
followers_url: string;
|
|
62
|
+
following_url: string;
|
|
63
|
+
gists_url: string;
|
|
64
|
+
starred_url: string;
|
|
65
|
+
subscriptions_url: string;
|
|
66
|
+
organizations_url: string;
|
|
67
|
+
repos_url: string;
|
|
68
|
+
events_url: string;
|
|
69
|
+
received_events_url: string;
|
|
70
|
+
type: string;
|
|
71
|
+
site_admin: boolean;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface ReleaseAsset {
|
|
75
|
+
url: string;
|
|
76
|
+
id: number;
|
|
77
|
+
node_id: string;
|
|
78
|
+
name: string;
|
|
79
|
+
label: string;
|
|
80
|
+
uploader: AuthorInfo;
|
|
81
|
+
content_type: string;
|
|
82
|
+
state: string;
|
|
83
|
+
size: number;
|
|
84
|
+
download_count: number;
|
|
85
|
+
created_at: string;
|
|
86
|
+
updated_at: string;
|
|
87
|
+
browser_download_url: string;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export interface ReleaseReactions {
|
|
91
|
+
url: string;
|
|
92
|
+
total_count: number;
|
|
93
|
+
"+1": number;
|
|
94
|
+
"-1": number;
|
|
95
|
+
laugh: number;
|
|
96
|
+
hooray: number;
|
|
97
|
+
confused: number;
|
|
98
|
+
heart: number;
|
|
99
|
+
rocket: number;
|
|
100
|
+
eyes: number;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface ReleaseInfo {
|
|
104
|
+
url: string;
|
|
105
|
+
assets_url: string;
|
|
106
|
+
upload_url: string;
|
|
107
|
+
html_url: string;
|
|
108
|
+
author: AuthorInfo;
|
|
109
|
+
node_id: string;
|
|
110
|
+
tag_name: string;
|
|
111
|
+
tag_commitish?: string;
|
|
112
|
+
name: string;
|
|
113
|
+
draft: boolean;
|
|
114
|
+
prerelease: boolean;
|
|
115
|
+
created_at: string;
|
|
116
|
+
published_at: string;
|
|
117
|
+
assets: ReleaseAsset[];
|
|
118
|
+
tarball_url: string;
|
|
119
|
+
zipball_url: string;
|
|
120
|
+
body: string;
|
|
121
|
+
reactions: ReleaseReactions
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export async function listReleases(opts: ListReleasesOptions): Promise<ReleaseInfo[]> {
|
|
125
|
+
const { repo, owner, accessToken } = opts;
|
|
126
|
+
const result = await new Octokit({ auth: accessToken }).repos.listReleases({ owner, repo });
|
|
127
|
+
return result.data as ReleaseInfo[];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export function newerVersion(latestVersion: string, currentVersion: string): boolean {
|
|
131
|
+
if (!latestVersion) {
|
|
132
|
+
return false
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (!currentVersion) {
|
|
136
|
+
return true
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const normalizedLatestVersion = latestVersion.replace(/^v/, "")
|
|
140
|
+
const normalizedCurrentVersion = currentVersion.replace(/^v/, "")
|
|
141
|
+
|
|
142
|
+
return gt(normalizedLatestVersion, normalizedCurrentVersion)
|
|
143
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { RestEndpointMethodTypes } from '@octokit/rest'
|
|
2
|
+
|
|
3
|
+
export type OctokitRelease = RestEndpointMethodTypes['repos']['getLatestRelease']['response']
|
|
4
|
+
export type OctokitReleaseAssets = OctokitRelease['data']['assets']
|
|
5
|
+
|
|
6
|
+
export interface Release {
|
|
7
|
+
repository: string
|
|
8
|
+
package: string
|
|
9
|
+
destination: string
|
|
10
|
+
version: string
|
|
11
|
+
extract: boolean
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface RepoInfo {
|
|
15
|
+
owner: string
|
|
16
|
+
repo: string
|
|
17
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
|
|
4
|
+
export const exists = async (filePath: string): Promise<boolean> => {
|
|
5
|
+
try {
|
|
6
|
+
await fs.promises.access(filePath)
|
|
7
|
+
return true
|
|
8
|
+
} catch {
|
|
9
|
+
return false
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const mkdir = async (dirname: string): Promise<void> => {
|
|
14
|
+
const isExist = await exists(dirname)
|
|
15
|
+
|
|
16
|
+
if (!isExist) {
|
|
17
|
+
await fs.promises.mkdir(dirname, { recursive: true })
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const ensureDirExist = async (filePath: string): Promise<void> => {
|
|
22
|
+
const dirname = path.dirname(filePath)
|
|
23
|
+
await mkdir(dirname)
|
|
24
|
+
}
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"patch": 2
|
|
20
20
|
};
|
|
21
21
|
module.exports = function incrementVersion(version, strategy, zeroLowerOrder = true, incrementBy = 1) {
|
|
22
|
-
const dashedParts = version.split("-"), currentVersionIsPreRelease = dashedParts.length > 1, parts = dashedParts[0].split(".").map(i => parseInt(i));
|
|
22
|
+
const dashedParts = version.split("-"), currentVersionIsPreRelease = dashedParts.length > 1, prefix = removePrefix(dashedParts), parts = dashedParts[0].split(".").map(i => parseInt(i));
|
|
23
23
|
let toIncrement = incrementLookup[(strategy || "").toLowerCase()];
|
|
24
24
|
if (toIncrement === undefined) {
|
|
25
25
|
throw new ZarroError(`Unknown version increment strategy: ${strategy}\n try one of 'major', 'minor' or 'patch'`);
|
|
@@ -43,8 +43,17 @@
|
|
|
43
43
|
}
|
|
44
44
|
const result = parts.join(".");
|
|
45
45
|
if (strategy != "prerelease") {
|
|
46
|
-
return result
|
|
46
|
+
return `${prefix}${result}`;
|
|
47
47
|
}
|
|
48
|
-
return `${result}-${generateVersionSuffix()}`;
|
|
48
|
+
return `${prefix}${result}-${generateVersionSuffix()}`;
|
|
49
49
|
};
|
|
50
|
+
function removePrefix(parts) {
|
|
51
|
+
var _a, _b, _c;
|
|
52
|
+
const match = parts[0].match(/^(?<prefix>[^.\d]+)?(?<version>[.\d]+)/), prefix = (_b = (_a = match === null || match === void 0 ? void 0 : match.groups) === null || _a === void 0 ? void 0 : _a["prefix"]) !== null && _b !== void 0 ? _b : "", version = (_c = match === null || match === void 0 ? void 0 : match.groups) === null || _c === void 0 ? void 0 : _c["version"];
|
|
53
|
+
if (!version) {
|
|
54
|
+
throw new Error(`'${parts[0]}' doesn't look like a version string?`);
|
|
55
|
+
}
|
|
56
|
+
parts[0] = version;
|
|
57
|
+
return prefix;
|
|
58
|
+
}
|
|
50
59
|
})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zarro",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.165.2",
|
|
4
4
|
"description": "Some glue to make gulp easier, perhaps even zero- or close-to-zero-conf",
|
|
5
5
|
"bin": {
|
|
6
6
|
"zarro": "./index.js"
|
|
@@ -91,6 +91,7 @@
|
|
|
91
91
|
},
|
|
92
92
|
"files": [
|
|
93
93
|
"gulp-tasks/**/*.js",
|
|
94
|
+
"gulp-tasks/modules/fetch-github-release/**/*.*",
|
|
94
95
|
"index-modules/**/*.js",
|
|
95
96
|
"types.d.ts",
|
|
96
97
|
"tsconfig.json"
|