diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 3d8c9dc7..80be0cd4 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -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 diff --git a/.github/actions-scripts/validate-release-version.js b/.github/actions-scripts/validate-release-version.js new file mode 100755 index 00000000..bb58c439 --- /dev/null +++ b/.github/actions-scripts/validate-release-version.js @@ -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); + } +} diff --git a/.github/workflows/publish-beta-package.yml b/.github/workflows/publish-beta-package.yml new file mode 100644 index 00000000..e912f9a0 --- /dev/null +++ b/.github/workflows/publish-beta-package.yml @@ -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 }}/ + diff --git a/.github/workflows/publish-prod-package.yml b/.github/workflows/publish-prod-package.yml new file mode 100644 index 00000000..dbb1b6ab --- /dev/null +++ b/.github/workflows/publish-prod-package.yml @@ -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 }}/ + diff --git a/.gitignore b/.gitignore index ac38884a..47b8b94b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ .DS_Store - +.idea .coverage node_modules umd diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 1152992b..00000000 --- a/.travis.yml +++ /dev/null @@ -1,88 +0,0 @@ -language: node_js -version: 1.0 -node_js: - - "node" -before_script: - - npm run build -deploy: - - # This Travis CI deploy configuration will automatically - # deploy builds triggered by tags denoting alpha, beta, - # or stable versions of v2 to HelloSign's S3 bucket so - # that they may be served and distributed globally via - # HelloSign's CDN powered by CloudFront. - # - # cdn.hellosign.com/public/js/embedded - - provider: s3 - skip_cleanup: true - access_key_id: $S3_ACCESS_KEY_ID - secret_access_key: $S3_SECRET_ACCESS_KEY - bucket: $S3_BUCKET - upload_dir: public/js/embedded/${TRAVIS_TAG} - local_dir: umd - on: - tags: true - - # This Travis CI deploy configuration will automatically - # deploy builds triggered by tags denoting only stable - # versions of v2 to npm tagged as "latest". - # - # npmjs.com/package/hellosign-embedded - - provider: npm - edge: true - skip_cleanup: true - email: $NPM_EMAIL_ADDRESS - api_key: $NPM_API_KEY - tag: latest - on: - tags: true - condition: $TRAVIS_TAG =~ ^v2\.[0-9]+\.[0-9]+$ - - # This Travis CI deploy configuration will automatically - # deploy builds triggered by tags denoting only alpha or - # beta versions of v2 to npm tagged as "next". - # - # npmjs.com/package/hellosign-embedded - - provider: npm - edge: true - skip_cleanup: true - email: $NPM_EMAIL_ADDRESS - api_key: $NPM_API_KEY - tag: next - on: - tags: true - condition: $TRAVIS_TAG =~ ^v2\.[0-9]+\.[0-9]+-(alpha|beta)\.[0-9]+$ - - # This Travis CI deploy configuration will automatically - # deploy builds triggered by tags denoting only stable - # versions of v2 to GitHub releases. - # - # github.com/hellosign/hellosign-embedded/releases - - provider: releases - skip_cleanup: true - api_key: $GITHUB_OAUTH_TOKEN - file_glob: true - file: umd/* - tag_name: $TRAVIS_TAG - target_commitish: $TRAVIS_COMMIT - on: - tags: true - condition: $TRAVIS_TAG =~ ^v2\.[0-9]+\.[0-9]+$ - - # This Travis CI deploy configuration will automatically - # deploy builds triggered by tags denoting only alpha or - # beta versions of v2 to GitHub releases and tagged as - # "prerelease". - # - # github.com/hellosign/hellosign-embedded/releases - - provider: releases - skip_cleanup: true - api_key: $GITHUB_OAUTH_TOKEN - file_glob: true - file: umd/* - tag_name: $TRAVIS_TAG - target_commitish: $TRAVIS_COMMIT - prerelease: true - on: - tags: true - condition: $TRAVIS_TAG =~ ^v2\.[0-9]+\.[0-9]+-(alpha|beta)\.[0-9]+$ diff --git a/CHANGELOG.md b/CHANGELOG.md index e59828ad..1fca9a36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,13 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. -### [2.11.1](https://github.com/hellosign/hellosign-embedded/compare/v2.11.0...v2.11.1) (2023-07-18) +## [2.12.0](https://github.com/hellosign/hellosign-embedded/compare/v2.11.1...v2.12.0) (2023-12-27) + +### Features + +* github actions replaces travis for ci/cd operations. Sign REF: SPDE-130 + +## [2.11.1](https://github.com/hellosign/hellosign-embedded/compare/v2.11.0...v2.11.1) (2023-07-18) ## [2.11.0](https://github.com/hellosign/hellosign-embedded/compare/v2.10.0...v2.11.0) (2023-07-18) @@ -18,12 +24,10 @@ All notable changes to this project will be documented in this file. See [standa ## [2.10.0](https://github.com/hellosign/hellosign-embedded/compare/v2.9.0...v2.10.0) (2021-05-18) - ### Features * Update node-sass and sass-loader ([0234daf](https://github.com/hellosign/hellosign-embedded/commit/0234daf5d9a8654df0313ae95b42eb56220cff23)) - ### Bug Fixes * Do not use self-closing tags in HTML markup ([9520b39](https://github.com/hellosign/hellosign-embedded/commit/9520b39f19fbe86c74d94fa3c331cee5a9cf064c)) diff --git a/README.md b/README.md index 97481df9..6344404f 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ [![Npm version][badge_npm-version]][external_npm] [![Npm downloads][badge_npm-downloads]][external_npm] -[![Travis][badge_travis]][external_travis] -[![David][badge_david]][external_david] +![Beta Build Status](https://github.com/hellosign/hellosign-embedded/actions/workflows/publish-beta-package.yml/badge.svg) +![Latest Build Status](https://github.com/hellosign/hellosign-embedded/actions/workflows/publish-prod-package.yml/badge.svg)
@@ -67,12 +67,10 @@ If you have any questions or issues with HelloSign Embedded or our API, please c -[changelog]: https://github.com/hellosign/hellosign-embedded/blob/master/CHANGELOG.md +[changelog]: https://github.com/hellosign/hellosign-embedded/blob/main/CHANGELOG.md [badge_npm-version]: https://img.shields.io/npm/v/hellosign-embedded.svg [badge_npm-downloads]: https://img.shields.io/npm/dm/hellosign-embedded.svg -[badge_david]: https://img.shields.io/david/hellosign/hellosign-embedded.svg -[badge_travis]: https://img.shields.io/travis/hellosign/hellosign-embedded/master.svg [wiki_home]: https://github.com/hellosign/hellosign-embedded/wiki [wiki_api-documentation]: https://github.com/hellosign/hellosign-embedded/wiki/API-Documentation-(v2) @@ -83,4 +81,5 @@ If you have any questions or issues with HelloSign Embedded or our API, please c [external_demo]: https://app.hellosign.com/api/embeddedTest [external_hellosign]: https://hellosign.com [external_npm]: https://npmjs.org/package/hellosign-embedded -[external_travis]: https://travis-ci.org/hellosign/hellosign-embedded?branch=master + + diff --git a/package.json b/package.json index 1d1154f5..45637d98 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hellosign-embedded", - "version": "2.11.1", + "version": "2.12.0", "description": "Embed HelloSign signature requests and templates from within your web application.", "main": "index.js", "license": "MIT", @@ -37,6 +37,8 @@ "tiny-emitter": "^2.1.0" }, "devDependencies": { + "@actions/github": "^5.1.1", + "@actions/core": "^1.10.1", "@babel/core": "^7.2.2", "@babel/plugin-proposal-class-properties": "^7.3.0", "@babel/plugin-proposal-object-rest-spread": "^7.3.2", @@ -55,6 +57,7 @@ "jest-runner-eslint": "^0.7.3", "node-sass": "^6.0.0", "sass-loader": "^5.0.0", + "semver": "^7.5.4", "standard-version": "^9.0.0", "style-loader": "^0.23.1", "url-polyfill": "^1.1.8",