Skip to content

Commit

Permalink
Initial version of action
Browse files Browse the repository at this point in the history
  • Loading branch information
svenstaro committed Aug 23, 2019
1 parent 337dba3 commit b46ad43
Show file tree
Hide file tree
Showing 9 changed files with 499 additions and 62 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules/
__tests__/runner/*
run.sh
5 changes: 2 additions & 3 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

The MIT License (MIT)

Copyright (c) 2018 GitHub, Inc. and contributors
Copyright (c) 2019 Sven-Hendrik Haase

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand All @@ -19,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
THE SOFTWARE.
88 changes: 83 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,87 @@
# JavaScript Action Template
# Upload files to a GitHub release

This template offers an easy way to get started writing a javascript action with TypeScript compile time support, unit testing with Jest and using the GitHub Actions Toolkit.
This action allows you to select which files to upload to the just-tagged release.
It runs on all operating systems types offered by GitHub.

## Getting Started
## Input variables:

See the walkthrough located [here](https://github.com/actions/toolkit/blob/master/docs/javascript-action.md).
You must provide:

In addition to walking your through how to create an action, it also provides strategies for versioning, releasing and referencing your actions.
- `repo_token`: Usually you'll want to set this to `${{ secrets.GITHUB_TOKEN }}`
- `file`: A local file to be uploaded as the asset.
- `asset_name`: The name the file gets as an asset on a release.
- `tag`: The tag to uploaded into. If you want the current event's tag, use `${{ github.event.ref }}`
- `overwrite`: If an asset with name already exists, overwrite it.

## Usage

This usage assumes you want to build on tag creations only.
This is a common use case as you will want to upload release binaries for your tags.

Simple example:

name: Publish

on:
create:
tags:

jobs:
build:
name: Publish binaries
runs-on: ubuntu-latest

steps:
- uses: hecrj/setup-rust-action@master
with:
rust-version: stable
- uses: actions/checkout@v1
- name: Build
run: cargo build --release
- name: Upload binaries to release
uses: svenstaro/upload-release-action@master
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: target/release/mything
asset_name: mything
tag: {{ github.event.ref }}
overwrite: true

Complex example with more operating systems:

name: Publish

on:
create:
tags:

jobs:
build:
name: Publish for ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-latest
artifact_name: mything
asset_name: mything-linux-amd64
- os: windows-latest
artifact_name: mything.exe
asset_name: mything-windows-amd64
- os: macos-latest
artifact_name: mything
asset_name: mything-macos-amd64

steps:
- uses: hecrj/setup-rust-action@master
with:
rust-version: stable
- uses: actions/checkout@v1
- name: Build
run: cargo build --release
- name: Upload binaries to release
uses: svenstaro/upload-release-action@master
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: target/release/${{ matrix.artifact_name }}
asset_name: ${{ matrix.asset_name }}
7 changes: 5 additions & 2 deletions __tests__/main.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
describe('TODO - Add a test suite', () => {
it('TODO - Add a test', async () => {});
import * as main from '../src/main';

// Frankly, tests would be entirely useless unless we can mock GitHub somehow.
describe('Upload Release Action', () => {
it('', async () => {});
});
21 changes: 14 additions & 7 deletions action.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
name: 'Node 12 Template Action'
description: 'Get started with Node actions'
author: 'GitHub'
inputs:
myInput:
description: 'Input to use'
default: 'world'
name: 'Upload files to a GitHub release'
description: 'Upload files to a GitHub release (cross-platform)'
author: 'Sven-Hendrik Haase'
inputs:
repo_token:
description: 'GitHub token'
file:
description: 'Local file to upload'
asset_name:
description: 'Name of the asset'
tag:
description: 'Tag to use as a release'
overwrite:
description: 'Overwrite the release in case it already exists'
runs:
using: 'node12'
main: 'lib/main.js'
92 changes: 92 additions & 0 deletions lib/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs = __importStar(require("fs"));
const core = __importStar(require("@actions/core"));
const github = __importStar(require("@actions/github"));
function get_release_by_tag(tag, octokit, context) {
return __awaiter(this, void 0, void 0, function* () {
try {
core.debug(`Getting release by tag ${tag}.`);
return yield octokit.repos.getReleaseByTag(Object.assign({}, context.repo, { tag: tag }));
}
catch (error) {
// If this returns 404, we need to create the release first.
if (error.status === 404) {
core.debug(`Release for tag ${tag} doesn't exist yet so we'll create it now.`);
return yield octokit.repos.createRelease(Object.assign({}, context.repo, { tag_name: tag }));
}
else {
throw error;
}
}
});
}
function upload_to_release(release, file, asset_name, tag, overwrite, octokit, context) {
return __awaiter(this, void 0, void 0, function* () {
const file_size = fs.statSync(file).size;
const file_bytes = fs.readFileSync(file);
// Check for duplicates.
const assets = yield octokit.repos.listAssetsForRelease(Object.assign({}, context.repo, { release_id: release.data.id }));
const duplicate_asset = assets.data.find(a => a.name === asset_name);
if (duplicate_asset !== undefined) {
if (overwrite === "true") {
core.debug(`An asset called ${asset_name} already exists in release ${tag} so we'll overwrite it.`);
yield octokit.repos.deleteReleaseAsset(Object.assign({}, context.repo, { asset_id: duplicate_asset.id }));
}
else {
core.setFailed(`An asset called ${asset_name} already exists.`);
return;
}
}
else {
core.debug(`No pre-existing asset called ${asset_name} found in release ${tag}. All good.`);
}
core.debug(`Uploading ${file} to ${asset_name} in release ${tag}.`);
yield octokit.repos.uploadReleaseAsset({
url: release.data.upload_url,
name: asset_name,
file: file_bytes,
headers: {
"content-type": "binary/octet-stream",
"content-length": file_size
},
});
});
}
function run() {
return __awaiter(this, void 0, void 0, function* () {
try {
const token = core.getInput('repo_token', { required: true });
const file = core.getInput('file', { required: true });
const asset_name = core.getInput('asset_name', { required: true });
const tag = core.getInput('tag', { required: true });
const overwrite = core.getInput('overwrite');
if (!fs.existsSync(file)) {
core.setFailed(`File ${file} wasn't found.`);
}
const octokit = new github.GitHub(token);
const context = github.context;
const release = yield get_release_by_tag(tag, octokit, context);
yield upload_to_release(release, file, asset_name, tag, overwrite, octokit, context);
}
catch (error) {
core.setFailed(error.message);
}
});
}
run();
Loading

0 comments on commit b46ad43

Please sign in to comment.