refactor for cross platform use
This commit is contained in:
86
src/github.ts
Normal file
86
src/github.ts
Normal file
@ -0,0 +1,86 @@
|
||||
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
|
||||
}
|
||||
|
||||
export interface Release {
|
||||
upload_url: string,
|
||||
html_url: string
|
||||
}
|
||||
|
||||
export const asset = (path: string): ReleaseAsset => {
|
||||
return {
|
||||
name: basename(path),
|
||||
mime: mimeOrDefault(path),
|
||||
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);
|
||||
console.log(`⬆️ Uploading ${name}...`);
|
||||
return await gh.repos.uploadReleaseAsset({
|
||||
url,
|
||||
headers: {
|
||||
"content-length": size,
|
||||
"content-type": mime
|
||||
},
|
||||
name,
|
||||
file
|
||||
});
|
||||
}
|
||||
|
||||
export const release = async (
|
||||
config: Config,
|
||||
gh: GitHub
|
||||
): Promise<Release> => {
|
||||
let [owner, repo] = config.github_repository.split("/");
|
||||
try {
|
||||
let release = await gh.repos.getReleaseByTag({
|
||||
owner,
|
||||
repo,
|
||||
tag: config.github_ref
|
||||
});
|
||||
return release.data;
|
||||
} catch (error) {
|
||||
if (error.status === 404) {
|
||||
const tag_name = config.github_ref.replace("refs/tags/", "");
|
||||
const name = config.input_name || tag_name;
|
||||
const body = config.input_body;
|
||||
const draft = config.input_draft;
|
||||
let release = await gh.repos.createRelease({
|
||||
owner,
|
||||
repo,
|
||||
tag_name,
|
||||
name,
|
||||
body,
|
||||
draft
|
||||
});
|
||||
return release.data;
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
27
src/main.ts
Normal file
27
src/main.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import * as fs from 'fs';
|
||||
import * as core from '@actions/core';
|
||||
import { GitHub } from '@actions/github';
|
||||
import { paths, parseConfig, isTag } from './util';
|
||||
import { release, upload } from './github';
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
const config = parseConfig(process.env);
|
||||
if (!isTag(config.github_ref)) {
|
||||
throw new Error(`⚠️ GitHub Releases requires a tag`);
|
||||
}
|
||||
// todo: validate github_ref is a tag
|
||||
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)
|
||||
});
|
||||
}
|
||||
console.log(`🎉 Release ready at ${rel.html_url}`)
|
||||
} catch (error) {
|
||||
core.setFailed(error.message);
|
||||
}
|
||||
}
|
||||
|
||||
run();
|
39
src/util.ts
Normal file
39
src/util.ts
Normal file
@ -0,0 +1,39 @@
|
||||
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,
|
||||
}
|
||||
|
||||
type Env = { [key: string]: string | undefined };
|
||||
|
||||
export const parseConfig = (env: Env): Config => {
|
||||
return {
|
||||
github_token: env.GITHUB_TOKEN || "",
|
||||
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'
|
||||
}
|
||||
}
|
||||
|
||||
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()));
|
||||
}, [])
|
||||
}
|
||||
|
||||
export const isTag = (ref: string): boolean => {
|
||||
return ref.startsWith("refs/tags/")
|
||||
}
|
Reference in New Issue
Block a user