Skip to content

Commit

Permalink
DE-6746: Add Release workflow
Browse files Browse the repository at this point in the history
Add a GitHub workflow which publishes the package to NPM
and API docs to `https://players.castlabs.com/react-dom/<version>/docs/`
when a new Release is manually created on GitHub.
The version is taken from the tag created with the Release on GitHub.

Also clean up the readme and the docs homepage.
  • Loading branch information
fingerartur committed Nov 28, 2023
1 parent faadc0f commit 2dd49bf
Show file tree
Hide file tree
Showing 14 changed files with 393 additions and 193 deletions.
11 changes: 11 additions & 0 deletions .github/actions/apply-version/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: 'Apply version'
description: 'Apply version to package.json, readme and docs, also update versioned links'

inputs:
version:
description: The SDK version
required: true

runs:
using: 'node16'
main: './main.js'
85 changes: 85 additions & 0 deletions .github/actions/apply-version/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
const fs = require('fs')
const path = require('path')
const execSync = require('child_process').execSync
const core = require('@actions/core')

/**
* @fileoverview Replace version and links to API docs with the current/fresh
* value where needed (package.json, readme, storybook intro).
*/

/**
* @param {string} filepath relative to project root
* @return {string} absolute path
*/
function file(filepath) {
return path.resolve(__dirname, `../../../${filepath}`)
}

const TOKENS = {
LINK_DOCS: 'CI_REPLACE_LINK_DOCS',
VERSION: 'CI_REPLACE_VERSION',
}

const FILES = {
README: file('README.md'),
STORYBOOK_INTRO: file('story/stories/Intro.mdx'),
}

const version = core.getInput('version', {required: true})

// Note: The trailing slash is very important here, it won't work without it.
const homepage = `https://players.castlabs.com/react-dom/${version}/docs/`

core.info(`API docs link is: ${homepage}`)

/**
* Set the "homepage" and "version" attribute in package.json
* @param {string} version
* @param {string} docsLink link to API docs
*/
function addLinkToPackageJson(version, docsLink) {
core.info(`Set package.json version and homepage link to docs`)
execSync(`
npm pkg set version=${version};
npm pkg set homepage=${docsLink};
`, { stdio: 'inherit' })
}

/**
* Replace token by link in the README.md file
* @param {string} link
*/
function addLinkToReadme(link) {
core.info(`Adding link to ${FILES.README}`)
replaceText(FILES.README, TOKENS.LINK_DOCS, link)
}

/**
* Replace token by version in Storybook Intro.mdx file
* @param {string} version
*/
function addVersionToStorybook(version) {
core.info(`Adding version to ${FILES.STORYBOOK_INTRO}`)
replaceText(FILES.STORYBOOK_INTRO, TOKENS.VERSION, version)
}

/**
* @param {string} filename file
* @param {string} token token to replace
* @param {string} text replacement text
*/
function replaceText(filename, token, text) {
const content = fs.readFileSync(filename, 'utf8')
fs.writeFileSync(filename, content.replace(token, text))
}

try {
addLinkToReadme(homepage)
addVersionToStorybook(version)
addLinkToPackageJson(version, homepage)
core.info('Success')
} catch (err) {
core.error('Failed to generated links to API docs' + err)
process.exit(1)
}
14 changes: 14 additions & 0 deletions .github/actions/publish/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: 'Publish'
description: 'Publish to NPM, if it is a beta version publish to beta channel'

inputs:
version:
description: The SDK version
required: true
dryRun:
description: If true, run the commands but don't publish to NPM
required: false

runs:
using: 'node16'
main: './main.js'
33 changes: 33 additions & 0 deletions .github/actions/publish/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const execSync = require('child_process').execSync
const core = require('@actions/core')

/**
* @fileoverview Publish to NPM, if the version is in the beta format
* (e.g. 1.2.3-beta.4 or 1.2.3-alpha.1 etc.) then publish to a beta channel.
*/

const version = core.getInput('version', {required: true})
const dryRun = core.getBooleanInput('dryRun')

const regexBetaVersion = /^\d+\.\d+\.\d+-(\w+)\.\d+$/;
const regexVersion = /^\d+\.\d+\.\d+$/;

const betaMatch = version.match(regexBetaVersion);

if (betaMatch) {
const betaLabel = betaMatch[1];
core.info(`Publishing a Beta version ${version}.`)
execSync(`npm publish ${dryRun ? '--dry-run' : ''} --tag ${betaLabel}`, { stdio: 'inherit' })
process.exit(0);
}

const isNormal = regexVersion.test(version);

if (isNormal) {
core.info(`Publishing version ${version}.`)
execSync(`npm publish ${dryRun ? '--dry-run' : ''}`, { stdio: 'inherit' })
process.exit(0);
}

core.error(`Invalid version format. Version: ${version}`);
process.exit(1);
15 changes: 8 additions & 7 deletions .github/workflows/ci-build.yml → .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: CI Build
name: Build

on:
push:
Expand All @@ -7,21 +7,22 @@ on:
pull_request:
branches:
- main

jobs:
build:
name: Build
runs-on: [ubuntu-latest]

steps:
- uses: actions/checkout@v3
- name: Checkout
uses: actions/checkout@v3

- uses: actions/setup-node@v3
name: Setup Node
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 16
cache: npm

- name: NPM Install
run: npm ci

Expand Down
76 changes: 76 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Publish

on:
release:
types: [released]

env:
NPM_TOKEN: ${{ secrets.CLPLAYERS_NPM_TOKEN_RW }}
VERSION: ${{ github.event.release.tag_name }}
WEB_PATH: "react-dom/${{ github.event.release.tag_name }}/docs/"

permissions:
contents: read # Permission for actions/checkout
id-token: write # Permission for aws-actions/configure-aws-credentials

jobs:
publish:
name: Publish
runs-on: [ubuntu-latest]
steps:
- name: Checkout Code
uses: actions/checkout@v3

- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: 16
cache: npm

- name: Install Dependencies
run: npm ci

- name: Apply version to package.json, readme and docs
uses: ./.github/actions/apply-version
with:
version: ${{ env.VERSION }}

## Publish the API docs

- name: Build Storybook
run: npm run build-storybook

- name: Assume AWS role
uses: aws-actions/configure-aws-credentials@v3
with:
role-to-assume: ${{ secrets.AWS_UPLOADER_ROLE_PLAYERS }}
aws-region: us-east-1

- name: Upload to S3
run: aws s3 cp --recursive "./dist/storybook" "${{ secrets.AWS_WEB_BUCKET }}/${{ env.WEB_PATH }}"
# Note: the default cache policy is 1 day, I think that's OK for now.
# In the future if traffic increases we can increase the expiration
# as much as we want.

## Publish the NPM package

- name: Write NPM RC File
run: |
echo '@castlabs:registry=https://registry.npmjs.org' > .npmrc
echo '//registry.npmjs.org/:_authToken=${NPM_TOKEN}' >> .npmrc
- name: Build
run: npm run build

- name: Publish to NPM
uses: ./.github/actions/publish
with:
version: ${{ env.VERSION }}
dryRun: false

- name: Add Job summary
run: |
echo '### NPM Release' >> $GITHUB_STEP_SUMMARY
echo "Released version ${{ env.VERSION }} of https://www.npmjs.com/package/@castlabs/prestoplay-react-components" >> $GITHUB_STEP_SUMMARY
echo '### Docs' >> $GITHUB_STEP_SUMMARY
echo "Published docs to https://players.castlabs.com/${{ env.WEB_PATH }}" >> $GITHUB_STEP_SUMMARY
Loading

0 comments on commit 2dd49bf

Please sign in to comment.