Skip to content

Add GitHub Actions workflow for release creation #16

Add GitHub Actions workflow for release creation

Add GitHub Actions workflow for release creation #16

name: Create release
on:
pull_request: # Temporarily add pull_request for testing
branches: main
workflow_dispatch:
inputs:
skip-release:
default: false
description: Skip release
type: boolean
defaults:
run:
shell: bash
env:
node-version: 22
jobs:
prepare:
name: Prepare
outputs:
version: ${{ steps.version.outputs.version }}
version-type: ${{ steps.version-type.outputs.version-type }}
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: ${{ env.node-version }}
- id: version-type
name: Determine version type
run: 'if [[ "$(cat ./package.json | jq -r ''.version'')" == *-0 ]]; then echo version-type=prerelease | tee --append $GITHUB_OUTPUT; else echo version-type=production | tee --append $GITHUB_OUTPUT; fi'
- if: steps.version-type.outputs.version-type != 'production'
name: Set version
run: |
# BRANCH_NAME=${{ github.ref }}
BRANCH_NAME=main
COMMITISH=${{ github.sha }}
NOW=$(date +%Y%m%d%H%M)
SHORT_COMMITISH=${COMMITISH:0:7}
# npm version simply ignoring the build metadata + (plus) sign, we need to use dot or hyphen instead.
npm version --no-git-tag-version $(echo $(cat ./package.json | jq -r '.version') | cut -d- -f1)-$BRANCH_NAME.$NOW.$SHORT_COMMITISH
- id: version
name: Get version
run: echo version=$(cat package.json | jq -r '.version') | tee --append $GITHUB_OUTPUT
build:
name: Build
permissions:
contents: read
needs: prepare
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: ${{ env.node-version }}
- run: npm version --no-git-tag-version ${{ needs.prepare.outputs.version }}
- run: npm clean-install
- env:
NODE_ENV: production
run: npm run build
- name: Pack as tarball
run: |
npm pack \
--workspace=./packages/core \
--workspace=./packages/api \
--workspace=./packages/component \
--workspace=./packages/bundle \
--workspace=./packages/fluent-theme
# - name: Generate SBOM
# # --workspace has no effect, the resulting SBOM still contains other packages in the workspace
# run: npm sbom --package-lock-only --sbom-format spdx --sbom-type library | tee ./sbom.spdx.json
- uses: actions/upload-artifact@v7
with:
name: tarball
path: ./*.tgz
- uses: actions/upload-artifact@v7
with:
name: bundle-iife
path: ./packages/bundle/dist/**/*
- uses: actions/upload-artifact@v7
with:
name: bundle-esm
path: ./packages/bundle/static/**/*
- uses: actions/upload-artifact@v7
with:
name: fluent-theme-iife
path: ./packages/fluent-theme/dist/**/*
- uses: actions/upload-artifact@v7
with:
name: fluent-theme-esm
path: ./packages/fluent-theme/static/**/*
# - name: Upload SBOM artifact
# uses: actions/upload-artifact@v7
# with:
# name: sbom
# path: ./sbom.spdx.json
upload-changelog:
name: Upload changelog
needs: prepare
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: ${{ env.node-version }}
- run: npm install --global keep-a-changelog@2 prettier
- if: needs.prepare.outputs.version-type != 'production'
name: Tag unreleased as latest
run: npx keep-a-changelog --format markdownlint --release=${{ needs.prepare.outputs.version }}
- name: Extract latest entry
run: npx keep-a-changelog --format markdownlint --latest-release-full | tee ./CHANGELOG.latest.md
- name: Format extracted entry
run: npx prettier CHANGELOG.latest.md --tab-width 3 --write
- name: Upload changelog
uses: actions/upload-artifact@v7
with:
name: changelog
path: ./CHANGELOG.latest.md
release:
name: Release
needs:
- build
- prepare
- upload-changelog
permissions:
contents: write
runs-on: ubuntu-latest
steps:
- name: Download artifact (tarball)
uses: actions/download-artifact@v8
with:
name: tarball
path: ./asset
- name: Download artifact (bundle-iife)
uses: actions/download-artifact@v8
with:
name: bundle-iife
path: ./asset
- name: Download artifact (changelog)
uses: actions/download-artifact@v8
with:
name: changelog
path: ./
# - name: Download artifact (sbom)
# uses: actions/download-artifact@v8
# with:
# name: sbom
# path: ./asset
- id: compute-hash
name: Compute build metadata
run: |
echo git-short-sha=`echo ${{ github.sha }} | cut -c 1-7` | tee --append $GITHUB_OUTPUT
echo release-date=`date "+%Y-%m-%d %R:%S"` | tee --append $GITHUB_OUTPUT
echo sha384-es5=`cat webchat-es5.js | openssl dgst -sha384 -binary | openssl base64 -A` | tee --append $GITHUB_OUTPUT
echo sha384-full=`cat webchat.js | openssl dgst -sha384 -binary | openssl base64 -A` | tee --append $GITHUB_OUTPUT
echo sha384-minimal=`cat webchat-minimal.js | openssl dgst -sha384 -binary | openssl base64 -A` | tee --append $GITHUB_OUTPUT
- name: Build release notes
run: |
tee ./release.txt <<EOF
This release is for internal testing only. **Please do not use this build in production environment.**
| Build time | Run ID | Source version | Git ref | Package version |
| - | - | - | - | - |
| ${{ steps.compute-hash.outputs.release-date }}Z | [\`${{ github.run_id }}\`](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) | [\`${{ steps.compute-hash.outputs.git-short-sha }}\`](https://github.com/${{ github.repository }}/commit/${{ github.sha }}) | \`${{ github.ref }}\` | \`${{ needs.prepare.outputs.version }}\` |
\`\`\`html
<script
crossorigin="anonymous"
integrity="sha384-${{ steps.compute-hash.outputs.sha384-full }}"
src="https://cdn.botframework.com/botframework-webchat@${{ needs.prepare.outputs.version }}/dist/webchat.js"
></script>
<script
crossorigin="anonymous"
integrity="sha384-${{ steps.compute-hash.outputs.sha384-es5 }}"
src="https://cdn.botframework.com/botframework-webchat@${{ needs.prepare.outputs.version }}/dist/webchat-es5.js"
></script>
<script
crossorigin="anonymous"
integrity="sha384-${{ steps.compute-hash.outputs.sha384-minimal }}"
src="https://cdn.botframework.com/botframework-webchat@${{ needs.prepare.outputs.version }}/dist/webchat-minimal.js"
></script>
\`\`\`
# Changelog
EOF
cat ./CHANGELOG.latest.md | tee --append ./release.txt
- env:
# Use actions/create-github-app-token if create release would need to trigger another workflow.
GH_TOKEN: ${{ github.token }}
id: release
name: Create release
# Do not upload assets while creating release, otherwise, it will not trigger "release created" event.
run: |
if [[ "${{ needs.prepare.outputs.version-type }}" == "prerelease" ]]; then PRERELEASE=1; fi
TAG=v${{ needs.prepare.outputs.version }}
gh release create $TAG \
--notes-file ./release.txt \
${PRERELEASE:+--prerelease} \
--repo ${{ github.repository }} \
--target ${{ github.ref }}
echo tag=$TAG | tee --append $GITHUB_OUTPUT
- env:
GH_TOKEN: ${{ github.token }}
name: Upload assets
run: |
gh release upload ${{ steps.release.outputs.tag }} \
--repo ${{ github.repository }} \
./asset/*.js \
./asset/*.tgz
# ./aseet/sbom.spdx.json