Skip to content
This repository was archived by the owner on Mar 4, 2021. It is now read-only.

Add capability of upload release asset via release tag #45

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ author: 'GitHub'
inputs:
upload_url:
description: 'The URL for uploading assets to the release'
required: true
required: false
release_tag:
description: 'The tag of release for uploading assets'
required: false
asset_path:
description: 'The path to the asset you want to upload'
required: true
Expand Down
38 changes: 36 additions & 2 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4114,16 +4114,50 @@ function octokitDebug (octokit) {
/***/ (function(module, __unusedexports, __webpack_require__) {

const core = __webpack_require__(470);
const { GitHub } = __webpack_require__(469);
const { GitHub, context } = __webpack_require__(469);
const fs = __webpack_require__(747);

async function getUploadUrlByReleaseTag(github, releaseTag) {
// Get owner and repo from context of payload that triggered the action
const { owner, repo } = context.repo;

// Get the default tag name from the triggered action when not given
const tagName = releaseTag || context.ref;

// This removes the 'refs/tags' portion of the string, i.e. from 'refs/tags/xxx' to 'xxx'
const tag = tagName.replace('refs/tags/', '');

// Get a release from the tag name
// API Documentation: https://developer.github.com/v3/repos/releases/#create-a-release
// Octokit Documentation: https://octokit.github.io/rest.js/#octokit-routes-repos-create-release
const response = await github.repos.getReleaseByTag({
owner,
repo,
tag
});

// Get the upload URL for the created Release from the response
const {
data: { upload_url: uploadUrl }
} = response;

return uploadUrl;
}

async function run() {
try {
// Get authenticated GitHub client (Ocktokit): https://github.com/actions/toolkit/tree/master/packages/github#usage
const github = new GitHub(process.env.GITHUB_TOKEN);

// Get the inputs from the workflow file: https://github.com/actions/toolkit/tree/master/packages/core#inputsoutputs
const uploadUrl = core.getInput('upload_url', { required: true });
const uploadUrlVar = core.getInput('upload_url', { required: false });
const releaseTag = core.getInput('release_tag', { required: false });

const uploadUrl = uploadUrlVar || (await getUploadUrlByReleaseTag(github, releaseTag));
if (!uploadUrl) {
throw new Error('UploadUrl was not supplied and was failed getting by releaseTag');
}

const assetPath = core.getInput('asset_path', { required: true });
const assetName = core.getInput('asset_name', { required: true });
const assetContentType = core.getInput('asset_content_type', { required: true });
Expand Down
38 changes: 36 additions & 2 deletions src/upload-release-asset.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,48 @@
const core = require('@actions/core');
const { GitHub } = require('@actions/github');
const { GitHub, context } = require('@actions/github');
const fs = require('fs');

async function getUploadUrlByReleaseTag(github, releaseTag) {
// Get owner and repo from context of payload that triggered the action
const { owner, repo } = context.repo;

// Get the default tag name from the triggered action when not given
const tagName = releaseTag || context.ref;

// This removes the 'refs/tags' portion of the string, i.e. from 'refs/tags/xxx' to 'xxx'
const tag = tagName.replace('refs/tags/', '');

// Get a release from the tag name
// API Documentation: https://developer.github.com/v3/repos/releases/#create-a-release
// Octokit Documentation: https://octokit.github.io/rest.js/#octokit-routes-repos-create-release
const response = await github.repos.getReleaseByTag({
owner,
repo,
tag
});

// Get the upload URL for the created Release from the response
const {
data: { upload_url: uploadUrl }
} = response;

return uploadUrl;
}

async function run() {
try {
// Get authenticated GitHub client (Ocktokit): https://github.com/actions/toolkit/tree/master/packages/github#usage
const github = new GitHub(process.env.GITHUB_TOKEN);

// Get the inputs from the workflow file: https://github.com/actions/toolkit/tree/master/packages/core#inputsoutputs
const uploadUrl = core.getInput('upload_url', { required: true });
const uploadUrlVar = core.getInput('upload_url', { required: false });
const releaseTag = core.getInput('release_tag', { required: false });

const uploadUrl = uploadUrlVar || (await getUploadUrlByReleaseTag(github, releaseTag));
if (!uploadUrl) {
throw new Error('UploadUrl was not supplied and was failed getting by releaseTag');
}

const assetPath = core.getInput('asset_path', { required: true });
const assetName = core.getInput('asset_name', { required: true });
const assetContentType = core.getInput('asset_content_type', { required: true });
Expand Down
51 changes: 50 additions & 1 deletion tests/upload-release-asset.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const run = require('../src/upload-release-asset');

/* eslint-disable no-undef */
describe('Upload Release Asset', () => {
let getReleaseByTag;
let uploadReleaseAsset;
let content;

Expand All @@ -19,6 +20,12 @@ describe('Upload Release Asset', () => {
}
});

getReleaseByTag = jest.fn().mockReturnValueOnce({
data: {
upload_url: 'upload_url'
}
});

fs.statSync = jest.fn().mockReturnValueOnce({
size: 527
});
Expand All @@ -31,19 +38,61 @@ describe('Upload Release Asset', () => {
repo: 'repo'
};

context.ref = 'refs/tags/release_tag';

const github = {
repos: {
getReleaseByTag,
uploadReleaseAsset
}
};

GitHub.mockImplementation(() => github);
});

test('Upload release asset endpoint is called', async () => {
test('Upload release asset endpoint is called via upload_url', async () => {
core.getInput = jest
.fn()
.mockReturnValueOnce('upload_url')
.mockReturnValueOnce(null)
.mockReturnValueOnce('asset_path')
.mockReturnValueOnce('asset_name')
.mockReturnValueOnce('asset_content_type');

await run();

expect(uploadReleaseAsset).toHaveBeenCalledWith({
url: 'upload_url',
headers: { 'content-type': 'asset_content_type', 'content-length': 527 },
name: 'asset_name',
file: content
});
});

test('Upload release asset endpoint is called via release_tag', async () => {
core.getInput = jest
.fn()
.mockReturnValueOnce(null)
.mockReturnValueOnce('release_tag')
.mockReturnValueOnce('asset_path')
.mockReturnValueOnce('asset_name')
.mockReturnValueOnce('asset_content_type');

await run();

expect(uploadReleaseAsset).toHaveBeenCalledWith({
url: 'upload_url',
headers: { 'content-type': 'asset_content_type', 'content-length': 527 },
name: 'asset_name',
file: content
});
});

test('Upload release asset endpoint is called via default release_tag', async () => {
core.getInput = jest
.fn()
.mockReturnValueOnce(null)
.mockReturnValueOnce(null)
.mockReturnValueOnce('asset_path')
.mockReturnValueOnce('asset_name')
.mockReturnValueOnce('asset_content_type');
Expand Down