Skip to content

Commit

Permalink
Added CI workflows (#118)
Browse files Browse the repository at this point in the history
- Implemented github workflows for building changes to master branch.
- Added automatic automatic build asset uploads when creating releases.
  • Loading branch information
haorldbchi authored Oct 8, 2021
1 parent 970b879 commit 8a585d1
Show file tree
Hide file tree
Showing 6 changed files with 410 additions and 2 deletions.
126 changes: 126 additions & 0 deletions .github/actions/artifacts.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { Octokit } from '@octokit/action';
import * as FS from 'fs';
import * as Path from 'path';

const log = console.log;

const OWNER = 'Chia-Network';
const REPO = 'bladebit';
const API_BASE = `/repos/${OWNER}/${REPO}`;

function failIf( condition, error )
{
if( condition )
throw new Error( error );
}

function failIfResponseIsNot( response, expectedCode, error )
{
if( response.status !== expectedCode )
throw new Error( error );
}

function failIfErrorResponse( response, error )
{
if( response.status !== 200 )
throw new Error( error );
}


async function getArtifactUrl( argv )
{
// Get args
// const version = argv[0].toLowerCase();
// const os = argv[1].toLowerCase();
// const arch = argv[2].toLowerCase();
// const ext = os === 'windows' ? 'zip' : 'tar.gz';

// const artifactName = `bladebit-v${version}-${os}-${arch}.${ext}`;
const artifactName = argv[0];

if( !artifactName )
throw new Error( 'No artifact name given.' );

const API = `${API_BASE}/actions/artifacts`;
const octokit = new Octokit();

let response = await octokit.request( `GET ${API}` );
failIfErrorResponse( response, 'Invalid artifacts response.' );

// log( `Looking for artifact for version ${opts.version}` );
const artifacts = response.data.artifacts;
// log( JSON.stringify( artifacts, 4 ) );

const artifact = artifacts.find( a => a.name === artifactName );
// log( JSON.stringify( artifact, 4 ) );

if( !artifact )
throw new Error( `Failed to find an artifact name '${artifactName}'.` );

if( artifact.expired )
throw new Error( `Artifact '${artifactName}' has expired.` );

response = await octokit.request( `GET ${API}/{artifact_id}/{archive_format}`, {
artifact_id : artifact.id,
archive_format: 'zip'
});
// log( JSON.stringify( response, 4 ) );

// Docs say 302, but the returned code is actually 200
failIfErrorResponse( response, 'Failed to retrieve artifact download url.' );

const downloadUrl = response.url;
return downloadUrl;
}

async function uploadReleaseAsset( argv )
{
const API = `${API_BASE}/releases`;

const version = argv[0];
const assetName = argv[1];
const assetPath = argv[2];
const tag = 'v' + version;

const octokit = new Octokit();

let response = await octokit.request( `GET ${API}` );
failIfErrorResponse( response, 'Failed to retrieve releases' );
// log( JSON.stringify( response.data, null, 4 ) );

// Find the specified release
const release = response.data.find( a => a.tag_name === tag );
failIf( !release, `Failed to obtain release for version ${version}` );
// log( JSON.stringify( release, null, 4 ) );

const asset = FS.readFileSync( assetPath );

// Upload the artifact to the release as an asset
response = await octokit.rest.repos.uploadReleaseAsset({
owner : OWNER,
repo : REPO,
release_id: release.id,
name : assetName,
data : asset,
});
failIfResponseIsNot( response, 201, `Failed to upload asset ${assetName}` );
}

async function main()
{
const command = process.argv[2];
const argv = process.argv.slice( 3 );

switch( command )
{
case 'get-artifact-url':
log( ( await getArtifactUrl( argv ) ) );
break;

case 'upload-release-asset':
log( ( await uploadReleaseAsset( argv ) ) );
break;
}
}

await main();
60 changes: 60 additions & 0 deletions .github/workflows/attach-release-assets.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Attach Release Assets
on:
workflow_dispatch:
release:
types: [created] # Note: Neither create nor publish trigger if a release is drafted first.
# In order of it to trigger the release needs to be published when created.

jobs:
upload-release-assets:
runs-on: ubuntu-20.04
steps:
- name: Checkout Repo
uses: actions/checkout@v2
with:
ref: master

# Setup Node
- uses: actions/setup-node@v2
with: { node-version: '14' }
- run: cd .github/actions && npm install @octokit/action

# Upload Artifacts as Release Assets
- name: Upload Release Assets
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
BB_VERSION=$(basename $GITHUB_REF)
BB_VERSION=${BB_VERSION:1}
echo "Release Version: $BB_VERSION"
artifacts=(
bladebit-v${BB_VERSION}-ubuntu-x86-64.tar.gz
bladebit-v${BB_VERSION}-centos-x86-64.tar.gz
bladebit-v${BB_VERSION}-ubuntu-arm64.tar.gz
bladebit-v${BB_VERSION}-centos-arm64.tar.gz
bladebit-v${BB_VERSION}-windows-x86-64.zip
)
mkdir -p bin
for artifact_name in "${artifacts[@]}"; do
echo "Fetching $artifact_name"
url=$(node .github/actions/artifacts.mjs get-artifact-url $artifact_name)
# Download zipped artifact and unzip the contents
response_code=$(curl -w "%{http_code}" -o "bin/${artifact_name}.zip" "$url")
if [[ $response_code -ne 200 ]]; then
>&2 echo "Failed to download artifact"
exit 1
fi
unzip -d bin "bin/${artifact_name}.zip"
# Upload artifact to release
echo "Uploading release asset '${artifact_name}'"
node .github/actions/artifacts.mjs upload-release-asset $BB_VERSION $artifact_name bin/$artifact_name
done
Loading

0 comments on commit 8a585d1

Please sign in to comment.