Skip to content

Commit 95de5a8

Browse files
DSE-415 :: Fix release artifacts for external consumers (#194)
* fix(release): publish tested release tarballs * feat(example-react-consumer-app): model external tarball consumption * fix(release): avoid validator self-match * fix(pr): address review feedback
1 parent a0b8e3f commit 95de5a8

29 files changed

+4809
-1055
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Release contract
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- '.github/workflows/release.yml'
7+
- '.github/workflows/release-contract.yml'
8+
- 'README.md'
9+
- 'UPGRADING.md'
10+
- 'docs/**'
11+
- 'package.json'
12+
- 'pnpm-lock.yaml'
13+
- 'packages/toolkit/package.json'
14+
- 'packages/react-components/package.json'
15+
- 'packages/react-components/README.md'
16+
- 'scripts/release/**'
17+
18+
jobs:
19+
validate:
20+
name: Validate release contract
21+
runs-on: ubuntu-latest
22+
23+
steps:
24+
- uses: actions/checkout@v4
25+
26+
- uses: actions/setup-node@v4
27+
with:
28+
node-version: '22.x'
29+
30+
- name: Enable Corepack and pnpm
31+
run: |
32+
corepack enable
33+
corepack prepare pnpm@10.29.2 --activate
34+
35+
- name: Install dependencies
36+
run: pnpm install
37+
38+
- name: Validate docs and release templates
39+
run: pnpm docs:release-contract
40+
41+
- name: Smoke test current release artifacts
42+
run: pnpm smoke:release-artifacts

.github/workflows/release.yml

Lines changed: 61 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -38,33 +38,46 @@ jobs:
3838
- name: Run tests
3939
run: pnpm test
4040

41+
- name: Validate release contract docs
42+
run: pnpm docs:release-contract
43+
4144
- name: Determine package and version
4245
id: package_info
4346
run: |
4447
TAG=${GITHUB_REF#refs/tags/}
4548
if [[ $TAG == react-v* ]]; then
4649
echo "PACKAGE=react-components" >> $GITHUB_OUTPUT
50+
echo "PACKAGE_SCOPE=@ourfuturehealth/react-components" >> $GITHUB_OUTPUT
51+
echo "PACKAGE_DIR=packages/react-components" >> $GITHUB_OUTPUT
4752
echo "VERSION=${TAG#react-v}" >> $GITHUB_OUTPUT
48-
echo "BUILD_CMD=build" >> $GITHUB_OUTPUT
4953
elif [[ $TAG == toolkit-v* ]]; then
5054
echo "PACKAGE=toolkit" >> $GITHUB_OUTPUT
55+
echo "PACKAGE_SCOPE=@ourfuturehealth/toolkit" >> $GITHUB_OUTPUT
56+
echo "PACKAGE_DIR=packages/toolkit" >> $GITHUB_OUTPUT
5157
echo "VERSION=${TAG#toolkit-v}" >> $GITHUB_OUTPUT
52-
echo "BUILD_CMD=zip" >> $GITHUB_OUTPUT
5358
else
5459
# Assume v* tags are toolkit (backward compatibility)
5560
echo "PACKAGE=toolkit" >> $GITHUB_OUTPUT
61+
echo "PACKAGE_SCOPE=@ourfuturehealth/toolkit" >> $GITHUB_OUTPUT
62+
echo "PACKAGE_DIR=packages/toolkit" >> $GITHUB_OUTPUT
5663
echo "VERSION=${TAG#v}" >> $GITHUB_OUTPUT
57-
echo "BUILD_CMD=zip" >> $GITHUB_OUTPUT
5864
fi
5965
60-
- name: Build release artifact
66+
- name: Build release artifacts
6167
run: |
6268
if [ "${{ steps.package_info.outputs.PACKAGE }}" == "toolkit" ]; then
6369
pnpm --filter=@ourfuturehealth/toolkit run zip
6470
else
6571
pnpm --filter=@ourfuturehealth/react-components run build
6672
fi
6773
74+
- name: Pack release tarball
75+
id: tarball
76+
run: |
77+
TARBALL_NAME=$(npm pack "./${{ steps.package_info.outputs.PACKAGE_DIR }}" --ignore-scripts | tail -n 1)
78+
echo "ASSET_NAME=${TARBALL_NAME}" >> $GITHUB_OUTPUT
79+
echo "ASSET_PATH=${GITHUB_WORKSPACE}/${TARBALL_NAME}" >> $GITHUB_OUTPUT
80+
6881
- name: Resolve toolkit asset details
6982
if: steps.package_info.outputs.PACKAGE == 'toolkit'
7083
id: toolkit_asset
@@ -74,30 +87,48 @@ jobs:
7487
echo "ASSET_PATH=$ASSET_PATH" >> $GITHUB_OUTPUT
7588
echo "ASSET_NAME=$ASSET_NAME" >> $GITHUB_OUTPUT
7689
90+
- name: Smoke test release tarball
91+
run: |
92+
./scripts/release/smoke-package-tarball.sh \
93+
--package-dir "${{ github.workspace }}/${{ steps.package_info.outputs.PACKAGE_DIR }}" \
94+
--tarball "${{ steps.tarball.outputs.ASSET_PATH }}" \
95+
--managers 'yarn,npm,pnpm'
96+
97+
- name: Render release notes
98+
id: release_notes
99+
run: |
100+
NOTES_PATH="${GITHUB_WORKSPACE}/release-notes.md"
101+
if [ "${{ steps.package_info.outputs.PACKAGE }}" == "toolkit" ]; then
102+
./scripts/release/render-release-notes.sh \
103+
--package "${{ steps.package_info.outputs.PACKAGE }}" \
104+
--tag "${GITHUB_REF_NAME}" \
105+
--version "${{ steps.package_info.outputs.VERSION }}" \
106+
--tarball "${{ steps.tarball.outputs.ASSET_NAME }}" \
107+
--zip "${{ steps.toolkit_asset.outputs.ASSET_NAME }}" > "${NOTES_PATH}"
108+
else
109+
./scripts/release/render-release-notes.sh \
110+
--package "${{ steps.package_info.outputs.PACKAGE }}" \
111+
--tag "${GITHUB_REF_NAME}" \
112+
--version "${{ steps.package_info.outputs.VERSION }}" \
113+
--tarball "${{ steps.tarball.outputs.ASSET_NAME }}" > "${NOTES_PATH}"
114+
fi
115+
echo "NOTES_PATH=${NOTES_PATH}" >> $GITHUB_OUTPUT
116+
77117
- name: Create or update release
78118
env:
79119
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
80120
run: |
81121
TAG="${GITHUB_REF_NAME}"
82-
RELEASE_BODY=$(cat <<EOF
83-
Release of **${{ steps.package_info.outputs.PACKAGE }}** version ${{ steps.package_info.outputs.VERSION }}
84-
85-
## Installation
86-
87-
\`\`\`json
88-
{
89-
"dependencies": {
90-
"@ourfuturehealth/${{ steps.package_info.outputs.PACKAGE }}": "github:ourfuturehealth/design-system-toolkit#${{ github.ref_name }}:packages/${{ steps.package_info.outputs.PACKAGE }}"
91-
}
92-
}
93-
\`\`\`
94-
EOF
95-
)
96-
97-
if gh release view "$TAG" >/dev/null 2>&1; then
98-
gh release edit "$TAG" --title "$TAG" --notes "$RELEASE_BODY"
122+
if gh release view "$TAG" --repo "${GITHUB_REPOSITORY}" >/dev/null 2>&1; then
123+
gh release edit "$TAG" \
124+
--repo "${GITHUB_REPOSITORY}" \
125+
--title "$TAG" \
126+
--notes-file "${{ steps.release_notes.outputs.NOTES_PATH }}"
99127
else
100-
gh release create "$TAG" --title "$TAG" --notes "$RELEASE_BODY"
128+
gh release create "$TAG" \
129+
--repo "${GITHUB_REPOSITORY}" \
130+
--title "$TAG" \
131+
--notes-file "${{ steps.release_notes.outputs.NOTES_PATH }}"
101132
fi
102133
103134
- name: Upload toolkit zip asset
@@ -108,3 +139,11 @@ jobs:
108139
gh release upload "${GITHUB_REF_NAME}" "${{ steps.toolkit_asset.outputs.ASSET_PATH }}" \
109140
--clobber \
110141
--repo "${GITHUB_REPOSITORY}"
142+
143+
- name: Upload package tarball asset
144+
env:
145+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
146+
run: |
147+
gh release upload "${GITHUB_REF_NAME}" "${{ steps.tarball.outputs.ASSET_PATH }}" \
148+
--clobber \
149+
--repo "${GITHUB_REPOSITORY}"

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ bower_components
2424
# Lock files (using pnpm, so ignore npm/yarn lock files)
2525
package-lock.json
2626
yarn.lock
27+
!packages/example-react-consumer-app/package-lock.json
2728

2829
# Editors
2930
.idea

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ This repository is organized as a monorepo containing:
1313

1414
- **Core toolkit** - SCSS/CSS design system and vanilla JavaScript components
1515
- **React components** (`packages/react-components/`) - React implementation of the design system
16-
- **Example consumer app** (`packages/example-react-consumer-app/`) - Demonstration of consuming React components
16+
- **Example consumer app** (`packages/example-react-consumer-app/`) - Standalone in-repo example of consuming the published React tarball contract
1717

1818
## Prerequisites
1919

@@ -53,7 +53,7 @@ pnpm install
5353
# Development workflows
5454
pnpm storybook # React component documentation (Storybook)
5555
pnpm dev:react-components # React component library development
56-
pnpm dev:react-consumer # Example consumer app with library watch
56+
pnpm dev:react-consumer # Example consumer app dev server (run npm install in that directory first)
5757
pnpm dev:site # Documentation site development
5858
pnpm dev:toolkit # Core toolkit development
5959
pnpm dev # Run all dev servers concurrently

0 commit comments

Comments
 (0)