This commit is contained in:
softprops 2019-09-09 21:20:59 +09:00
parent 624fcca9a1
commit ef96a2eb52
7 changed files with 158 additions and 102 deletions

View file

@ -1,30 +1,25 @@
//import * as assert from "assert";
//const assert = require('assert');
import * as assert from 'assert';
import { mimeOrDefault, asset } from '../src/github';
import * as assert from "assert";
import { mimeOrDefault, asset } from "../src/github";
describe('github', () => {
describe('mimeOrDefault', () => {
it('returns a specific mime for common path', async () => {
assert.equal(mimeOrDefault('foo.tar.gz'), 'application/gzip')
});
it('returns default mime for uncommon path', async () => {
assert.equal(mimeOrDefault('foo.uncommon'), 'application/octet-stream')
});
});
describe("github", () => {
describe("mimeOrDefault", () => {
it("returns a specific mime for common path", async () => {
assert.equal(mimeOrDefault("foo.tar.gz"), "application/gzip");
});
it("returns default mime for uncommon path", async () => {
assert.equal(mimeOrDefault("foo.uncommon"), "application/octet-stream");
});
});
describe('asset', () => {
it('derives asset info from a path', async () => {
const {
name,
mime,
size,
file
} = asset('tests/data/foo/bar.txt');
assert.equal(name, 'bar.txt');
assert.equal(mime, 'text/plain');
assert.equal(size, 10);
assert.equal(file.toString(), 'release me')
});
})
describe("asset", () => {
it("derives asset info from a path", async () => {
const { name, mime, size, file } = asset("tests/data/foo/bar.txt");
assert.equal(name, "bar.txt");
assert.equal(mime, "text/plain");
assert.equal(size, 10);
assert.equal(file.toString(), "release me");
});
});
});

View file

@ -1,19 +1,21 @@
import { isTag, paths } from '../src/util';
import * as assert from 'assert';
import { isTag, paths } from "../src/util";
import * as assert from "assert";
describe('util', () => {
describe('isTag', () => {
it('returns true for tags', async () => {
assert.equal(isTag('refs/tags/foo'), true)
describe("util", () => {
describe("isTag", () => {
it("returns true for tags", async () => {
assert.equal(isTag("refs/tags/foo"), true);
});
it ('returns false for other kinds of refs', async () => {
assert.equal(isTag('refs/heads/master'), false)
})
})
it("returns false for other kinds of refs", async () => {
assert.equal(isTag("refs/heads/master"), false);
});
});
describe('paths', () => {
it('resolves files given a set of paths', async () => {
assert.deepStrictEqual(paths(["tests/data/**/*"]), ['tests/data/foo/bar.txt'])
describe("paths", () => {
it("resolves files given a set of paths", async () => {
assert.deepStrictEqual(paths(["tests/data/**/*"]), [
"tests/data/foo/bar.txt"
]);
});
})
});
});

65
package-lock.json generated
View file

@ -1172,8 +1172,13 @@
"version": "2.20.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
"integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==",
"dev": true,
"optional": true
"dev": true
},
"commandpost": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/commandpost/-/commandpost-1.4.0.tgz",
"integrity": "sha512-aE2Y4MTFJ870NuB/+2z1cXBhSBBzRydVVjzhFC4gtenEhpnj15yu0qptWGJsO9YGrcPZ3ezX8AWb1VA391MKpQ==",
"dev": true
},
"component-emitter": {
"version": "1.3.0",
@ -1386,6 +1391,18 @@
"safer-buffer": "^2.1.0"
}
},
"editorconfig": {
"version": "0.15.3",
"resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz",
"integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==",
"dev": true,
"requires": {
"commander": "^2.19.0",
"lru-cache": "^4.1.5",
"semver": "^5.6.0",
"sigmund": "^1.0.1"
}
},
"emoji-regex": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
@ -3445,6 +3462,16 @@
"js-tokens": "^3.0.0 || ^4.0.0"
}
},
"lru-cache": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
"integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
"dev": true,
"requires": {
"pseudomap": "^1.0.2",
"yallist": "^2.1.2"
}
},
"macos-release": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz",
@ -3995,6 +4022,12 @@
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
"dev": true
},
"prettier": {
"version": "1.18.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-1.18.2.tgz",
"integrity": "sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw==",
"dev": true
},
"pretty-format": {
"version": "24.9.0",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz",
@ -4017,6 +4050,12 @@
"sisteransi": "^1.0.3"
}
},
"pseudomap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
"dev": true
},
"psl": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.3.1.tgz",
@ -4334,6 +4373,12 @@
"integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==",
"dev": true
},
"sigmund": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
"integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=",
"dev": true
},
"signal-exit": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
@ -4844,6 +4889,16 @@
"integrity": "sha512-lmQ4L+J6mnu3xweP8+rOrUwzmN+MRAj7TgtJtDaXE5PMyX2kCrklhg3rvOsOIfNeAWMQWO2F1GPc1kMD2vLAfw==",
"dev": true
},
"typescript-formatter": {
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/typescript-formatter/-/typescript-formatter-7.2.2.tgz",
"integrity": "sha512-V7vfI9XArVhriOTYHPzMU2WUnm5IMdu9X/CPxs8mIMGxmTBFpDABlbkBka64PZJ9/xgQeRpK8KzzAG4MPzxBDQ==",
"dev": true,
"requires": {
"commandpost": "^1.0.0",
"editorconfig": "^0.15.0"
}
},
"uglify-js": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz",
@ -5099,6 +5154,12 @@
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
"dev": true
},
"yallist": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
"dev": true
},
"yargs": {
"version": "13.3.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz",

View file

@ -6,7 +6,8 @@
"main": "lib/main.js",
"scripts": {
"build": "tsc",
"test": "jest"
"test": "jest",
"fmt": "prettier --write 'src/**/*.ts' '__tests__/**/*.ts'"
},
"repository": {
"type": "git",
@ -30,7 +31,9 @@
"@types/node": "^12.7.4",
"jest": "^24.8.0",
"jest-circus": "^24.7.1",
"prettier": "1.18.2",
"ts-jest": "^24.0.2",
"typescript": "^3.5.1"
"typescript": "^3.5.1",
"typescript-formatter": "^7.2.2"
}
}

View file

@ -1,19 +1,19 @@
import { GitHub } from '@actions/github';
import { Config } from './util';
import { lstatSync, readFileSync } from 'fs';
import { getType } from 'mime';
import { basename } from 'path';
import { GitHub } from "@actions/github";
import { Config } from "./util";
import { lstatSync, readFileSync } from "fs";
import { getType } from "mime";
import { basename } from "path";
export interface ReleaseAsset {
name: string,
mime: string,
size: number,
file: Buffer
name: string;
mime: string;
size: number;
file: Buffer;
}
export interface Release {
upload_url: string,
html_url: string
upload_url: string;
html_url: string;
}
export const asset = (path: string): ReleaseAsset => {
@ -23,39 +23,31 @@ export const asset = (path: string): ReleaseAsset => {
size: lstatSync(path).size,
file: readFileSync(path)
};
}
};
export const mimeOrDefault = (path: string): string => {
return getType(path) || "application/octet-stream";
}
};
export const upload = async (
gh: GitHub,
url: string,
path: string
): Promise<any> => {
let {
name,
size,
mime,
file
} = asset(path);
let { name, size, mime, file } = asset(path);
console.log(`⬆️ Uploading ${name}...`);
return await gh.repos.uploadReleaseAsset({
url,
headers: {
headers: {
"content-length": size,
"content-type": mime
},
name,
file
});
}
};
export const release = async (
config: Config,
gh: GitHub
): Promise<Release> => {
export const release = async (config: Config, gh: GitHub): Promise<Release> => {
const [owner, repo] = config.github_repository.split("/");
const tag = config.github_ref.replace("refs/tags/", "");
try {
@ -88,8 +80,10 @@ export const release = async (
return release(config, gh);
}
} else {
console.log(`Unexpected error fetching GitHub release for tag ${config.github_ref}: ${error}`);
console.log(
`Unexpected error fetching GitHub release for tag ${config.github_ref}: ${error}`
);
throw error;
}
}
}
};

View file

@ -1,9 +1,8 @@
import { paths, parseConfig, isTag } from './util';
import { release, upload } from './github';
import { setFailed } from '@actions/core';
import { GitHub } from '@actions/github';
import { env } from 'process';
import { paths, parseConfig, isTag } from "./util";
import { release, upload } from "./github";
import { setFailed } from "@actions/core";
import { GitHub } from "@actions/github";
import { env } from "process";
async function run() {
try {
@ -14,11 +13,11 @@ async function run() {
const gh = new GitHub(config.github_token);
let rel = await release(config, gh);
if (config.input_files) {
paths(config.input_files).forEach(async (path) => {
await upload(gh, rel.upload_url, path)
paths(config.input_files).forEach(async path => {
await upload(gh, rel.upload_url, path);
});
}
console.log(`🎉 Release ready at ${rel.html_url}`)
console.log(`🎉 Release ready at ${rel.html_url}`);
} catch (error) {
console.log(`Error: ${error}`);
setFailed(error.message);

View file

@ -1,16 +1,16 @@
import * as glob from 'glob';
import { lstatSync } from 'fs';
import * as glob from "glob";
import { lstatSync } from "fs";
export interface Config {
github_token: string,
github_ref: string,
github_repository: string,
// user provided
input_name?: string,
input_body?: string,
input_body_path?: string,
input_files?: string[],
input_draft?: boolean,
github_token: string;
github_ref: string;
github_repository: string;
// user provided
input_name?: string;
input_body?: string;
input_body_path?: string;
input_files?: string[];
input_draft?: boolean;
}
type Env = { [key: string]: string | undefined };
@ -18,22 +18,24 @@ type Env = { [key: string]: string | undefined };
export const parseConfig = (env: Env): Config => {
return {
github_token: env.GITHUB_TOKEN || "",
github_ref: (env.GITHUB_REF || ""),
github_ref: env.GITHUB_REF || "",
github_repository: env.GITHUB_REPOSITORY || "",
input_name: env.INPUT_NAME,
input_body: env.INPUT_BODY,
input_body_path: env.INPUT_BODY_PATH,
input_files: (env.INPUT_FILES || "").split(","),
input_draft: env.INPUT_DRAFT === 'true'
}
}
input_draft: env.INPUT_DRAFT === "true"
};
};
export const paths = (patterns: string[]): string[] => {
return patterns.reduce((acc: string[], pattern: string): string[] => {
return acc.concat(glob.sync(pattern).filter(path => lstatSync(path).isFile()));
}, [])
}
return acc.concat(
glob.sync(pattern).filter(path => lstatSync(path).isFile())
);
}, []);
};
export const isTag = (ref: string): boolean => {
return ref.startsWith("refs/tags/")
}
return ref.startsWith("refs/tags/");
};