Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SPDE-130: Github Actions CI/CD [deprecating travis] #187

Merged
merged 8 commits into from
Dec 28, 2023
Merged
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
20 changes: 18 additions & 2 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,24 @@ Welcome! HelloSign Embedded is an open source project which allows HelloSign API
## Pull Requests

1. Fork the HelloSign Embedded repository.
2. Create a new branch for each feature, fix or improvement.
3. Send a pull request from each feature branch to the **`develop`** branch.
2. Create a new branch for your changes from the latest `main` branch
3. Make your changes
4. Increment the version number in [packages.json](package.json)
5. Add description of changes (matching format) to [CHANGELOG.md](/CHANGELOG.md)
6. Open a pull request, triggering a github action that does the following:
1. verify the version
2. build beta package
3. test beta package
4. generate a github tag for beta release
5. publish beta package to npm
6. publish to our s3 staging CDN
7. Once the pull request is merged to `main`, github actions:
1. verifies the live version
2. build package
3. test package
4. generate github release tag
5. publish to npm
6. publish to our S3 CDN

## License

Expand Down
80 changes: 80 additions & 0 deletions .github/actions-scripts/validate-release-version.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#!/usr/bin/env node

const { context, getOctokit } = require('@actions/github');
const { setOutput } = require('@actions/core');

const semver = require('semver');
const process = require('process');

console.assert(process.env.GITHUB_TOKEN, "GITHUB_TOKEN not present");

const octokit = getOctokit(process.env.GITHUB_TOKEN);
const workspace = process.env.GITHUB_WORKSPACE;

const beta_version_limit = 10;

const {
repo: { owner, repo },
payload: { number },
} = context;
console.assert(number, "number not present");

const gh_api_header = { headers: { 'X-GitHub-Api-Version': '2022-11-28' } }

main();

async function validateReleaseVersion() {

const { version } = require(`${workspace}/package.json`);

const { data: latest } = await octokit.request(`GET /repos/${owner}/${repo}/releases/latest`, gh_api_header)

// Version set in package.json must be greater than latest
console.log("Package Version: ", version, "Latest Version: ", latest.name)
if (! semver.gt(version, latest.name)) {
console.log("version property in package.json must be greater than: ", latest.name)
process.exit(1);
}
return version;
}


async function validateBetaVersion( version, beta_inc = 0 ) {

let beta_version = `${version}-beta.${beta_inc}`
console.log("Beta Version: ", beta_version)

if (beta_inc > beta_version_limit) {
console.log("Too many beta versions! (arbitrary limitation) ", beta_inc)
process.exit(1);
}

try {
const { data: beta_tag } = await octokit.request(
`GET /repos/${owner}/${repo}/git/refs/tags/${beta_version}`,
gh_api_header
)
console.log(`Tag exists (${beta_tag.ref}) bumping beta version and retrying`)
return validateBetaVersion( version, ++beta_inc );
} catch (error) {
if (error.status === 404) {
console.log(`OK to publish, no tag @ 'git/refs/tags/${beta_version}'`)
return beta_version;
} else {
console.log("Unknown oktokit error ", error.message)
process.exit(1);
}
}

return beta_version;
}

async function main() {
const version = await validateReleaseVersion();
if (process.argv[2] === '--beta') {
const beta_version = await validateBetaVersion(version);
setOutput("version", beta_version);
} else {
setOutput("version", version);
}
}
92 changes: 92 additions & 0 deletions .github/workflows/publish-beta-package.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: Sign Embedded Beta Package

on:
pull_request:
branches: [ "main" ]

env:
NPM_REGISTRY_URL: "https://registry.npmjs.com"
CDN_AWS_PUBLISH_ROLE: arn:aws:iam::654344198836:role/github-actions-oidc-role-nonprod-sign-embedded
CDN_BUCKET: cdn.staging-hellosign.com
CDN_PATH: public/js/embedded
AWS_REGION: us-east-1
jobs:
build:
permissions:
id-token: write # This is required for requesting the JWT
contents: write # This is required for publishing releases
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.x] # we should pull this from a common place

steps:
- uses: actions/checkout@v4

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
registry-url: ${{ env.NPM_REGISTRY_URL }}

- name: Build
run: |
npm install
npm run build

- name: Test
run: |
npm test

- name: Validate Semver
id: version
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: .github/actions-scripts/validate-release-version.js --beta

- name: Set Beta Version
env:
PACKAGE_VERSION: ${{ steps.version.outputs.version }}
run: |
echo "Setting beta version ${PACKAGE_VERSION}"
npm version ${PACKAGE_VERSION} --no-git-tag-version

- name: Pack
run: |
npm pack --pack-destination="./umd"

- name: Create tag
uses: actions/github-script@v5
with:
script: |
github.rest.git.createRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: 'refs/tags/${{ steps.version.outputs.version }}',
tag_name: 'v${{ steps.version.outputs.version }}',
name: 'v${{ steps.version.outputs.version }}',
draft: true,
prerelease: true,
sha: context.sha
})

- name: Publish Beta
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_CONFIG_PROVENANCE: true
run: |
npm publish --tag beta --provenance --access=public

- name: Configure AWS credentials for Non-Prod
id: awskeys
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ env.CDN_AWS_PUBLISH_ROLE }}
aws-region: ${{ env.AWS_REGION }}

- name: Copy dev build to nonprod cdn
run: aws s3 cp umd/embedded.development.js s3://${{ env.CDN_BUCKET }}/${{ env.CDN_PATH }}/v${{ steps.version.outputs.version }}/

- name: Copy minified build to nonprod cdn
run: aws s3 cp umd/embedded.production.min.js s3://${{ env.CDN_BUCKET }}/${{ env.CDN_PATH }}/v${{ steps.version.outputs.version }}/

84 changes: 84 additions & 0 deletions .github/workflows/publish-prod-package.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: Sign Embedded Latest Package

on:
push:
branches: [ "main" ]

env:
NPM_REGISTRY_URL: "https://registry.npmjs.com"
CDN_AWS_PUBLISH_ROLE: arn:aws:iam::301904545275:role/github-actions-oidc-role-prod-sign-embedded
CDN_BUCKET: cdn.hellosign.com
CDN_PATH: public/js/embedded
AWS_REGION: us-east-1
jobs:
build:
permissions:
id-token: write # This is required for requesting the JWT
contents: write # This is required for publishing releases
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.x] # we should pull this from a common place

steps:
- uses: actions/checkout@v4

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
registry-url: ${{ env.NPM_REGISTRY_URL }}

- name: Build
run: |
npm install
npm run build

- name: Test
run: |
npm test

- name: Validate Semver
id: version
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: .github/actions-scripts/validate-release-version.js

- name: Announce version
run: |
echo "v${{ steps.version.outputs.version }} is the proposed new version."

- name: Pack
run: |
npm pack --pack-destination="./umd"

- name: Create Release
uses: actions/github-script@v5
with:
script: |
github.rest.repos.createRelease({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: 'v${{ steps.version.outputs.version }}',
});

- name: Publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_CONFIG_PROVENANCE: true
run: |
npm publish --provenance --access=public

- name: Configure AWS credentials for Prod
id: awskeys
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ env.CDN_AWS_PUBLISH_ROLE }}
aws-region: ${{ env.AWS_REGION }}

- name: Copy dev build to cdn
run: aws s3 cp umd/embedded.development.js s3://${{ env.CDN_BUCKET }}/${{ env.CDN_PATH }}/v${{ steps.version.outputs.version }}/

- name: Copy minified build to nonprod cdn
run: aws s3 cp umd/embedded.production.min.js s3://${{ env.CDN_BUCKET }}/${{ env.CDN_PATH }}/v${{ steps.version.outputs.version }}/

2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.DS_Store

.idea
.coverage
node_modules
umd
88 changes: 0 additions & 88 deletions .travis.yml

This file was deleted.

Loading
Loading