refactor: revamp setup action with typescript (#18)

This PR revamps setup action with typescript and 
1) add a new job to verify `dist` folder complication
2) update viable version to 1.1.0 and 1.0.1

---------

Signed-off-by: Billy Zha <jinzha1@microsoft.com>
This commit is contained in:
Billy Zha 2023-09-08 16:01:37 +08:00 committed by GitHub
parent 8368cef253
commit 1aa9a00ef8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 7368 additions and 155 deletions

47
.github/workflows/check-dist.yml vendored Normal file
View File

@ -0,0 +1,47 @@
# Copyright The ORAS Authors.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
name: Check dist/
on:
push:
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
workflow_dispatch:
jobs:
check-dist:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: remove js files in dist/
run: find dist/ -type f \( -name "*.json" -o -name "*.js" -o -name "*.js.map" \) -delete
- name: Setup Node 16.x
uses: actions/setup-node@v3
with:
node-version: 16.x
cache: npm
- name: Install dependencies
run: npm install
- name: Rebuild the dist/ directory
run: npm run build
- name: Compare the expected and actual dist/ directories
run: |
if [ "$(git diff --ignore-space-at-eol dist/ | wc -l)" -gt "0" ]; then
echo "DIFFERENCES DETECTED: 'npm run build' is needed after code changes. See status below:"
git diff
exit 1
fi

View File

@ -35,8 +35,8 @@ jobs:
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
version:
- 0.15.1
- 1.0.0
- 1.0.1
- 1.1.0
fail-fast: true
steps:
- name: Checkout

View File

@ -20,7 +20,7 @@ inputs:
version:
description: Version of ORAS CLI to install
required: false
default: 1.0.0
default: 1.1.0
runs:
using: node16
main: dist/index.js
main: dist/index.js

2
dist/README.md vendored
View File

@ -1,6 +1,6 @@
# Publishing
The content in this `dist` folder is auto-generated after editing `../index.js` by
The content in this `dist` folder is auto-generated by
```sh
npm run build

7022
dist/index.js vendored

File diff suppressed because one or more lines are too long

1
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,68 +0,0 @@
// Copyright The ORAS Authors.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
const os = require('os');
const core = require('@actions/core');
const tc = require('@actions/tool-cache');
// Map arch to go releaser arch
// Reference: https://nodejs.org/api/os.html#os_os_arch
function mapArch(arch) {
const mappings = {
arm: 'armv7',
x64: 'amd64'
};
return mappings[arch] || arch;
}
// Map os to go releaser os
// Reference: https://nodejs.org/api/os.html#os_os_platform
function mapOS(os) {
const mappings = {
win32: 'windows'
};
return mappings[os] || os;
}
// Get the URL to download asset
function getDownloadURL(version) {
const platform = os.platform();
const filename = `oras_${version}_${mapOS(platform)}_${mapArch(os.arch())}`;
const extension = platform === 'win32' ? 'zip' : 'tar.gz';
return `https://github.com/oras-project/oras/releases/download/v${version}/${filename}.${extension}`;
}
// Download and install ORAS CLI of the specified version
async function setup() {
try {
// Download ORAS CLI of the specified version
const version = core.getInput('version');
const donwloadURL = getDownloadURL(version)
const assetPath = await tc.downloadTool(donwloadURL);
// Extract the tarball/zipball onto host runner
const extract = donwloadURL.endsWith('.zip') ? tc.extractZip : tc.extractTar;
const pathToCLI = await extract(assetPath);
// Expose the tool by adding it to the PATH
core.addPath(pathToCLI);
} catch (e) {
core.setFailed(e);
}
}
module.exports = setup
if (require.main === module) {
setup();
}

111
package-lock.json generated
View File

@ -1,7 +1,7 @@
{
"name": "setup-oras",
"version": "0.1.0",
"lockfileVersion": 2,
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
@ -10,7 +10,10 @@
"license": "Apache-2.0",
"dependencies": {
"@actions/core": "^1.10.0",
"@actions/tool-cache": "^2.0.1"
"@actions/tool-cache": "^2.0.1",
"@types/node": "^20.4.0",
"@vercel/ncc": "^0.36.1",
"typescript": "^5.2.2"
}
},
"node_modules/@actions/core": {
@ -31,17 +34,17 @@
}
},
"node_modules/@actions/http-client": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
"integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.1.1.tgz",
"integrity": "sha512-qhrkRMB40bbbLo7gF+0vu+X+UawOvQQqNAA/5Unx774RS8poaOhThDOG6BGmxvAnxhQnDp2BG/ZUm65xZILTpw==",
"dependencies": {
"tunnel": "^0.0.6"
}
},
"node_modules/@actions/io": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.2.tgz",
"integrity": "sha512-d+RwPlMp+2qmBfeLYPLXuSRykDIFEwdTA0MMxzS9kh4kvP1ftrc/9fzy6pX6qAjthdXruHQ6/6kjT/DNo5ALuw=="
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.3.tgz",
"integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q=="
},
"node_modules/@actions/tool-cache": {
"version": "2.0.1",
@ -65,6 +68,19 @@
"uuid": "bin/uuid"
}
},
"node_modules/@types/node": {
"version": "20.5.9",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.9.tgz",
"integrity": "sha512-PcGNd//40kHAS3sTlzKB9C9XL4K0sTup8nbG5lC14kzEteTNuAFh9u5nA0o5TWnSG2r/JNPRXFVcHJIIeRlmqQ=="
},
"node_modules/@vercel/ncc": {
"version": "0.36.1",
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.36.1.tgz",
"integrity": "sha512-S4cL7Taa9yb5qbv+6wLgiKVZ03Qfkc4jGRuiUQMQ8HGBD5pcNRnHeYM33zBvJE4/zJGjJJ8GScB+WmTsn9mORw==",
"bin": {
"ncc": "dist/ncc/cli.js"
}
},
"node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
@ -81,6 +97,18 @@
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
}
},
"node_modules/typescript": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
"integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
@ -89,72 +117,5 @@
"uuid": "dist/bin/uuid"
}
}
},
"dependencies": {
"@actions/core": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
"integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
"requires": {
"@actions/http-client": "^2.0.1",
"uuid": "^8.3.2"
}
},
"@actions/exec": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz",
"integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==",
"requires": {
"@actions/io": "^1.0.1"
}
},
"@actions/http-client": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
"integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
"requires": {
"tunnel": "^0.0.6"
}
},
"@actions/io": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.2.tgz",
"integrity": "sha512-d+RwPlMp+2qmBfeLYPLXuSRykDIFEwdTA0MMxzS9kh4kvP1ftrc/9fzy6pX6qAjthdXruHQ6/6kjT/DNo5ALuw=="
},
"@actions/tool-cache": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@actions/tool-cache/-/tool-cache-2.0.1.tgz",
"integrity": "sha512-iPU+mNwrbA8jodY8eyo/0S/QqCKDajiR8OxWTnSk/SnYg0sj8Hp4QcUEVC1YFpHWXtrfbQrE13Jz4k4HXJQKcA==",
"requires": {
"@actions/core": "^1.2.6",
"@actions/exec": "^1.0.0",
"@actions/http-client": "^2.0.1",
"@actions/io": "^1.1.1",
"semver": "^6.1.0",
"uuid": "^3.3.2"
},
"dependencies": {
"uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
}
}
},
"semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
},
"tunnel": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
},
"uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
}
}
}

View File

@ -2,9 +2,8 @@
"name": "setup-oras",
"version": "0.1.0",
"description": "Set up your GitHub Actions workflow with a specific version of ORAS",
"main": "index.js",
"scripts": {
"build": "ncc build index.js -o dist --source-map --minify --license licenses.txt"
"build": "ncc build src/setup.ts"
},
"repository": {
"type": "git",
@ -19,6 +18,9 @@
"homepage": "https://github.com/oras-project/setup-oras#readme",
"dependencies": {
"@actions/core": "^1.10.0",
"@actions/tool-cache": "^2.0.1"
"@actions/tool-cache": "^2.0.1",
"@types/node": "^20.4.0",
"@vercel/ncc": "^0.36.1",
"typescript": "^5.2.2"
}
}

26
src/lib/checksum.ts Normal file
View File

@ -0,0 +1,26 @@
// Copyright The ORAS Authors.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import * as crypto from 'crypto';
import * as fs from 'fs';
// hash computes SH256 of file at path.
export function hash(path: string): Promise<string> {
return new Promise((resolve, reject) => {
const hash = crypto.createHash('sha256');
const stream = fs.createReadStream(path);
stream.on('error', err => reject(err));
stream.on('data', chunk => hash.update(chunk));
stream.on('end', () => resolve(hash.digest('hex')));
});
}

View File

@ -0,0 +1,74 @@
{
"1.0.1": {
"darwin": {
"amd64": {
"checksum": "34f11536dc191f9ad4288649f97ef69b478548f891c932c9732307f064ed3331",
"url": "https://github.com/oras-project/oras/releases/download/v1.0.1/oras_1.0.1_darwin_amd64.tar.gz"
},
"arm64": {
"checksum": "faa0181799f0e0295d7df188441a1f8869da78a50da4cf7fb03cf35dc746b178",
"url": "https://github.com/oras-project/oras/releases/download/v1.0.1/oras_1.0.1_darwin_arm64.tar.gz"
}
},
"linux": {
"amd64": {
"checksum": "6b51b87360d373dd3c19b91d2627d2efd320513380a878b6f06702f72fe8c5ab",
"url": "https://github.com/oras-project/oras/releases/download/v1.0.1/oras_1.0.1_linux_amd64.tar.gz"
},
"arm64": {
"checksum": "ae1884ae17b7ae7ce694c63d51a52ab0dac1f2c0ca384163455c1e96c5663db0",
"url": "https://github.com/oras-project/oras/releases/download/v1.0.1/oras_1.0.1_linux_arm64.tar.gz"
},
"armv7": {
"checksum": "f31bc8eab3ed2f368056df3eb5761f40d90dfbd8272bec58d83961f41ebbf3fb",
"url": "https://github.com/oras-project/oras/releases/download/v1.0.1/oras_1.0.1_linux_armv7.tar.gz"
},
"s390x": {
"checksum": "2a63313a99dd45c448c022a303941e1f5b47b8fdf3493c593b026de384a284b6",
"url": "https://github.com/oras-project/oras/releases/download/v1.0.1/oras_1.0.1_linux_s390x.tar.gz"
}
},
"windows": {
"amd64": {
"checksum": "0b9c50eda7aa384d435b31710264d08c77a5e83ee6560ee6e13ca46a6acec1ba",
"url": "https://github.com/oras-project/oras/releases/download/v1.0.1/oras_1.0.1_windows_amd64.zip"
}
}
},
"1.1.0": {
"darwin": {
"amd64": {
"checksum": "f8ac5dea53dd9331cf080f1025f0612e7b07c5af864a4fd609f97d8946508e45",
"url": "https://github.com/oras-project/oras/releases/download/v1.1.0/oras_1.1.0_darwin_amd64.tar.gz"
},
"arm64": {
"checksum": "d52d3140b0bb9f7d7e31dcbf2a513f971413769c11f7d7a5599e76cc98e45007",
"url": "https://github.com/oras-project/oras/releases/download/v1.1.0/oras_1.1.0_darwin_arm64.tar.gz"
}
},
"linux": {
"amd64": {
"checksum": "e09e85323b24ccc8209a1506f142e3d481e6e809018537c6b3db979c891e6ad7",
"url": "https://github.com/oras-project/oras/releases/download/v1.1.0/oras_1.1.0_linux_amd64.tar.gz"
},
"arm64": {
"checksum": "e450b081f67f6fda2f16b7046075c67c9a53f3fda92fd20ecc59873b10477ab4",
"url": "https://github.com/oras-project/oras/releases/download/v1.1.0/oras_1.1.0_linux_arm64.tar.gz"
},
"armv7": {
"checksum": "def86e7f787f8deee50bb57d1c155201099f36aa0c6700d3b525e69ddf8ae49b",
"url": "https://github.com/oras-project/oras/releases/download/v1.1.0/oras_1.1.0_linux_armv7.tar.gz"
},
"s390x": {
"checksum": "067600d61d5d7c23f7bd184cff168ad558d48bed99f6735615bce0e1068b1d77",
"url": "https://github.com/oras-project/oras/releases/download/v1.1.0/oras_1.1.0_linux_s390x.tar.gz"
}
},
"windows": {
"amd64": {
"checksum": "2ac83631181d888445e50784a5f760f7f9d97fba3c089e79b68580c496fe68cf",
"url": "https://github.com/oras-project/oras/releases/download/v1.1.0/oras_1.1.0_windows_amd64.zip"
}
}
}
}

84
src/lib/release.ts Normal file
View File

@ -0,0 +1,84 @@
// Copyright The ORAS Authors.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import * as os from 'os';
import releaseJson from './data/releases.json';
// release is the type of official ORAS CLI release
interface releases {
[version: string]: {
[platform: string]: {
[arch: string]: {
checksum: string,
url: string
}
}
}
}
// Get release info of a certain verion of ORAS CLI
export function getReleaseInfo(version: string) {
const releases = releaseJson as releases;
if (!(version in releases)) {
console.log(`official ORAS CLI releases does not contain version ${version}`)
throw new Error(`official ORAS CLI releases does not contain version ${version}`);
}
const platform = mapPlatform();
const arch = mapArch();
const download = releases[version][platform][arch];
if (!download) {
throw new Error(`official ORAS CLI releases does not contain version ${version}, platform ${platform}, arch ${arch} is not supported`);
}
return download;
}
// getPlatform maps os.platform() to ORAS supported platforms.
export function mapPlatform(): string {
const platform: string = os.platform();
switch (platform) {
case 'linux':
return 'linux';
case 'darwin':
return 'darwin';
case 'win32':
return 'windows';
default:
throw new Error(`unsupported platform: ${platform}`);
}
}
// mapArch maps os.arch() to ORAS supported architectures.
export function mapArch(): string {
const architecture: string = os.arch();
switch (architecture) {
case 'x64':
return 'amd64';
case 'arm64':
return 'arm64';
case 'arm64':
return 'arm64';
case 's390':
return 's390x';
case 'arm':
return 'armv7';
default:
throw new Error(`unsupported architecture: ${architecture}`);
}
}
export function getBinaryExtension(): string {
const platform = mapPlatform();
return platform === 'windows' ? '.exe' : '';
}

56
src/setup.ts Normal file
View File

@ -0,0 +1,56 @@
// Copyright The ORAS Authors.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import * as core from '@actions/core';
import * as tc from '@actions/tool-cache';
import { getReleaseInfo } from './lib/release';
import { hash } from './lib/checksum';
// setup sets up the ORAS CLI
async function setup(): Promise<void> {
try {
// inputs from user
const version: string = core.getInput('version');
// download ORAS CLI and validate checksum
const info = getReleaseInfo(version);
const url = info.url;
console.log(`downloading ORAS CLI from ${url}`);
const pathToTarball: string = await tc.downloadTool(url);
console.log("downloading ORAS CLI completed");
const checksum = await hash(pathToTarball);
if (checksum !== info.checksum) {
throw new Error(`checksum of downloaded ORAS CLI ${checksum} does not match expected checksum ${info.checksum}`);
}
console.log("successfully verified downloaded release checksum");
// extract the tarball/zipball onto host runner
const extract = url.endsWith('.zip') ? tc.extractZip : tc.extractTar;
const pathToCLI: string = await extract(pathToTarball);
// add `ORAS` to PATH
core.addPath(pathToCLI);
} catch (e) {
if (e instanceof Error) {
core.setFailed(e);
} else {
core.setFailed('unknown error during ORAS setup');
}
}
}
export = setup;
if (require.main === module) {
setup();
}

15
tsconfig.json Normal file
View File

@ -0,0 +1,15 @@
{
"compilerOptions": {
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"strict": true, /* Enable all strict type-checking options. */
"sourceMap": true, /* Generates corresponding '.map' file. */
"outDir": "./dist", /* Redirect output structure to the directory. */
"rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
"skipLibCheck": true, /* Skip type checking all .d.ts files. */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
"resolveJsonModule": true, /* Allows importing modules with a .json extension. */
},
"exclude": ["node_modules"]
}