Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
7 changes: 4 additions & 3 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ on:

jobs:
common:
uses: City-of-Helsinki/.github/.github/workflows/ci-node.yml@main
secrets: inherit
uses: City-of-Helsinki/.github/.github/workflows/ci-pnpm-node.yml@main
Comment thread
Riippi marked this conversation as resolved.
secrets:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
with:
node-version: 22
node-version: 24.x
22 changes: 11 additions & 11 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,19 @@ jobs:
build-stable:
needs: release-please
if: ${{ needs.release-please.outputs.release_created }}
uses: City-of-Helsinki/.github/.github/workflows/ci-node.yml@main
uses: City-of-Helsinki/.github/.github/workflows/ci-pnpm-node.yml@main
Comment thread
Riippi marked this conversation as resolved.
secrets: inherit
with:
node-version: '22'
upload_artifacts: true
skip_sonar: true
node-version: '24'
upload-artifacts: true
skip-sonar: true

publish:
needs: build-stable
secrets: inherit
uses: City-of-Helsinki/.github/.github/workflows/ci-npm-publish.yml@main
with:
node-version: '22'
node-version: '24'
use-ci-build: true

# 3. CANARY RELEASE FLOW (Runs on every push to main, EXCLUDING schedule)
Expand All @@ -48,12 +48,12 @@ jobs:
build-canary:
# This conditional ensures it runs ONLY when the workflow was triggered by a commit push.
if: github.event_name == 'push'
uses: City-of-Helsinki/.github/.github/workflows/ci-node.yml@main
uses: City-of-Helsinki/.github/.github/workflows/ci-pnpm-node.yml@main
secrets: inherit
with:
node-version: '22'
upload_artifacts: true
skip_sonar: true
node-version: '24'
upload-artifacts: true
skip-sonar: true

publish-npm-canary:
# This conditional is redundant but good practice; it will only run if its dependency runs.
Expand All @@ -62,6 +62,6 @@ jobs:
secrets: inherit
uses: City-of-Helsinki/.github/.github/workflows/ci-npm-publish.yml@main
with:
node-version: '22'
node-version: '24'
use-ci-build: true
canary: true
4 changes: 2 additions & 2 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
yarn doctoc . -u
yarn lint-staged --relative
pnpm exec doctoc . -u
pnpm exec lint-staged --relative
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.14.0
v24.0.0
34 changes: 12 additions & 22 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,42 +1,32 @@
# ===============================================
FROM registry.access.redhat.com/ubi9/nodejs-22 AS appbase
FROM helsinki.azurecr.io/ubi9/nodejs-24-pnpm-builder-base AS appbase
Comment thread
Riippi marked this conversation as resolved.
# ===============================================

# Set environment
ARG PORT=3000
ENV PORT $PORT
ENV PORT=$PORT

WORKDIR /app

# Install yarn
USER root
RUN curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | tee /etc/yum.repos.d/yarn.repo && \
yum -y install yarn

# Yarn version
ENV YARN_VERSION 1.22.22
RUN yarn policies set-version ${YARN_VERSION}


# Set npm log verbosity level
ENV NPM_CONFIG_LOGLEVEL warn
ENV NPM_CONFIG_LOGLEVEL=warn

# Global npm dependencies in a non-root user directory
ENV NPM_CONFIG_PREFIX=/app/.npm-global
ENV PATH=$PATH:/app/.npm-global/bin

# Set NODE_ENV to development in the development container
ARG NODE_ENV=development
ENV NODE_ENV $NODE_ENV
ENV NODE_ENV=$NODE_ENV

# Copy package.json and yarn.lock files
COPY --chown=default:root package*.json *yarn* ./
# Copy package.json and pnpm-lock.yaml files
COPY --chown=default:root package*.json pnpm-lock.yaml ./

# Make scripts in dependencies available through path
ENV PATH /app/node_modules/.bin:$PATH
ENV PATH=/app/node_modules/.bin:$PATH

# Install dependencies including storybook addons
RUN yarn && yarn cache clean
RUN pnpm install --frozen-lockfile --ignore-scripts && pnpm store prune

# =============================
FROM appbase AS development
Expand All @@ -46,29 +36,29 @@ FROM appbase AS development
COPY --chown=default:root . .

# Start command for development
CMD ["yarn", "dev:no-open"]
CMD ["pnpm", "run", "dev:no-open"]

# =============================
FROM appbase AS staticbuilder
# =============================

# Set NODE_ENV to production for build
ARG NODE_ENV=production
ENV NODE_ENV $NODE_ENV
ENV NODE_ENV=$NODE_ENV

# Copy all files, including .mdx stories
COPY --chown=default:root . .

# Build Storybook
RUN yarn build-storybook --loglevel error
RUN pnpm run build-storybook --loglevel error

# =============================
FROM appbase AS production
# =============================

# Set NODE_ENV to production in the production container
ARG NODE_ENV=production
ENV NODE_ENV $NODE_ENV
ENV NODE_ENV=$NODE_ENV

# Copy build folder
COPY --from=staticbuilder --chown=default:root /app/storybook-static/ /app/storybook-static/
Expand Down
83 changes: 37 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,17 @@ data using [Helsinki Design System](https://github.com/City-of-Helsinki/helsinki
- [Use as a application dependency](#use-as-a-application-dependency)
- [Folder-based links](#folder-based-links)
- [Tarball-based links](#tarball-based-links)
- [Use portals (with monorepos and Yarn)](#use-portals-with-monorepos-and-yarn)
- [Use portals (with monorepos and pnpm)](#use-portals-with-monorepos-and-pnpm)
- [Testing](#testing)
- [Testing in IDE terminal](#testing-in-ide-terminal)
- [Usage](#usage)
- [Releases, changelogs and deployments](#releases-changelogs-and-deployments)
- [Releases and changelogs](#releases-and-changelogs)
- [Conventional Commits](#conventional-commits)
- [Releasable units](#releasable-units)
- [Configuration](#configuration)
- [Troubleshooting release-please](#troubleshooting-release-please)
- [Fix merge conflicts by running release-please -action manually](#fix-merge-conflicts-by-running-release-please--action-manually)
- [Deployments](#deployments)
- [Publishing new versions manually without release-please](#publishing-new-versions-manually-without-release-please)
- [Publishing new versions manually without release-please](#publishing-new-versions-manually-without-release-please)
- [Known issues](#known-issues)
- [Contributing](#contributing)
- [Issues](#issues)
Expand Down Expand Up @@ -75,7 +74,7 @@ It provides:
## Installation

```bash
yarn add @city-of-helsinki/react-helsinki-headless-cms
pnpm add @city-of-helsinki/react-helsinki-headless-cms
```

## Development
Expand All @@ -96,16 +95,16 @@ The general requirements for new Component development:

| Name | Purpose | Useful Options |
| ----------------------- | -------------------------------------------------------------------------------------------------------- | ----------------------------- |
| `yarn dev` | Starts storybook environment that can be used for developing components. | |
| `yarn typecheck` | Runs the ts type check in the project components. | |
| `yarn lint` | Lints the application to be according to quality standards (eslint) and formatting standards (prettier). | `--fix`: fix fixable problems |
| `yarn test` | Runs tests with jest. | `--watch`: enable watch mode |
| `yarn test-storybook` | Runs storybook accessibility tests jest. | |
| `yarn build` | Builds application with rollup. | |
| `yarn docker:dev` | Runs the application with docker with Development target environment. | |
| `yarn docker:prod` | Runs the application with docker with Production target environment. | |
| `yarn docker:down` | Shuts down the docker environment. | |
| `yarn generate:graphql` | Generates / updates GraphQL schema for the project. | |
| `pnpm dev` | Starts storybook environment that can be used for developing components. | |
| `pnpm typecheck` | Runs the ts type check in the project components. | |
| `pnpm lint` | Lints the application to be according to quality standards (eslint) and formatting standards (prettier). | `--fix`: fix fixable problems |
| `pnpm test` | Runs tests with jest. | `--watch`: enable watch mode |
| `pnpm test-storybook` | Runs storybook accessibility tests jest. | |
Comment thread
Riippi marked this conversation as resolved.
Outdated
| `pnpm build` | Builds application with rollup. | |
| `pnpm docker:dev` | Runs the application with docker with Development target environment. | |
| `pnpm docker:prod` | Runs the application with docker with Production target environment. | |
| `pnpm docker:down` | Shuts down the docker environment. | |
| `pnpm generate:graphql` | Generates / updates GraphQL schema for the project. | |

**NOTE: To manually publish a new version to the NPM, you will need the credentials that can be found from the City of Helsinki Culture and Leisure's Vault-service.**

Expand All @@ -119,7 +118,7 @@ You can use docker local environment for development:

Alternatively, the local environment can be used:

`yarn dev`
`pnpm dev`

### Module structure

Expand All @@ -138,12 +137,12 @@ This project uses [Husky](https://typicode.github.io/husky/#/) to manage Git hoo
The pre-commit hook is configured to run the following commands:

```sh
yarn doctoc .
yarn lint-staged --relative
pnpm exec doctoc .
pnpm exec lint-staged --relative
Comment thread
Riippi marked this conversation as resolved.
Outdated
```

- `yarn doctoc .`: This command updates the table of contents in your markdown files.
- `yarn lint-staged --relative`: This command runs linting on staged files to ensure they meet the project's coding standards. The lint-staged configuration can be found from [package.json](./package.json).
- `pnpm exec doctoc .`: This command updates the table of contents in your markdown files.
Comment thread
Riippi marked this conversation as resolved.
Outdated
- `pnpm exec lint-staged --relative`: This command runs linting on staged files to ensure they meet the project's coding standards. The lint-staged configuration can be found from [package.json](./package.json).
- Using `--relative` flag to reduce command line length,
as the combined length of all the absolute paths for a large commit can get quite long

Expand Down Expand Up @@ -182,7 +181,7 @@ The project is using the Storybook 10.

**NOTE: Storybook version 10 may require the `playwright-chromium` installation.**

The `yarn dev` command will start `storybook` in port `6006`. When you make changes in `src`, they'll be automatically updated to `storybook`.
The `pnpm dev` command will start `storybook` in port `6006`. When you make changes in `src`, they'll be automatically updated to `storybook`.

### Apollo

Expand Down Expand Up @@ -233,11 +232,11 @@ This project uses `rollup` for its final bundle.
The easiest way to test the React Helsinki Headless CMS -library is to install it as a dependency of an application by using a local relative path:

- https://docs.npmjs.com/cli/v9/configuring-npm/package-json#local-paths
- https://yarnpkg.com/protocol/file
- https://pnpm.io/cli/add#install-from-local-file-system (pnpm supports the same `file:` protocol)

The steps to use the local relative path as a dependency:

1. Build the React Helsinki Headless CMS -library with `yarn build`. You should now have a `/dist` -folder that contains the built library package.
1. Build the React Helsinki Headless CMS -library with `pnpm build`. You should now have a `/dist` -folder that contains the built library package.
2. Add the `/dist`-directory as a dependency. Remember to use the right relative local path:

```
Expand All @@ -250,12 +249,12 @@ The steps to use the local relative path as a dependency:

#### Tarball-based links

When file: points to a .tgz file, Yarn will transparently let you require files from within the archive. For the node_modules linker, it means that the archive will be unpacked into the generated node_modules folder.
When file: points to a .tgz file, pnpm will transparently let you require files from within the archive. For the node_modules linker, it means that the archive will be unpacked into the generated node_modules folder.

You can create a tarball by first building the package and then calling `pack`

1. `yarn build`
2. `yarn pack`
1. `pnpm build`
2. `pnpm pack`

The steps to use the local tarball as a dependency:

Expand All @@ -267,9 +266,9 @@ The steps to use the local tarball as a dependency:
}
```

#### Use portals (with monorepos and Yarn)
#### Use portals (with monorepos and pnpm)

> See more: https://yarnpkg.com/protocol/portal
> See more: https://pnpm.io/cli/link

The `portal:` protocol is similar to the `link:` protocol (it must be a relative path to a folder which will be made available without copies), but the target is assumed to be a package instead.
Comment thread
Riippi marked this conversation as resolved.
Outdated

Expand All @@ -290,7 +289,7 @@ The `portal:` protocol is specifically designed for linking local directories (o
}
```

3. Clean and Install: *If you have a conflicting dependency* in the root `package.json`, delete it and run yarn install from the monorepo root.
3. Clean and Install: *If you have a conflicting dependency* in the root `package.json`, delete it and run pnpm install from the monorepo root.
Comment thread
Riippi marked this conversation as resolved.
Outdated

## Testing

Expand All @@ -301,7 +300,7 @@ The test could be run from the Storybook UI (Accessibility tab of the Story) or
### Testing in IDE terminal

```bash
yarn test-storybook
pnpm test-storybook
```

After executing the script, you will get the Axe Accessibility testing report in the terminal window.
Expand Down Expand Up @@ -345,17 +344,15 @@ function App() {

```

## Releases, changelogs and deployments

The used environments are listed in [Service environments](#service-environments).
## Releases and changelogs

The application uses automatic semantic versions and is released using [Release Please](https://github.com/googleapis/release-please).

> Release Please is a GitHub Action that automates releases for you. It will create a GitHub release and a GitHub Pull Request with a changelog based on conventional commits.

Each time you merge a "normal" pull request, the release-please-action will create or update a "Release PR" with the changelog and the version bump related to the changes (they're named like `release-please--branches--master--components--react-helsinki-headless-cms`).

To create a new release for an app, this release PR is merged, which creates a new release with release notes and a new tag. This tag will be picked by Azure pipeline and trigger a new deployment to staging. From there, the release needs to be manually released to production.
To create a new release, merge the release PR. This creates a new release with notes and a new tag. The release workflow then builds and publishes the package to npm.

When merging release PRs, make sure to use the "Rebase and merge" (or "Squash and merge") option, so that Github doesn't create a merge commit. All the commits must follow the conventional commits format. This is important, because the release-please-action does not work correctly with merge commits (there's an open issue you can track: [Chronological commit sorting means that merged PRs can be ignored ](https://github.com/googleapis/release-please/issues/1533)).

Expand Down Expand Up @@ -407,27 +404,21 @@ Sometimes there might be a merge conflict in release PR - this should resolve it

There's also a CLI for debugging and manually running releases available for release-please: [release-please-cli](https://github.com/googleapis/release-please/blob/main/docs/cli.md)

### Deployments

When a Release-Please pull request is merged and a version tag is created (or a proper tag name for a commit is manually created), this tag will be picked by Azure pipeline, which then triggers a new deployment to staging. From there, the deployment needs to be manually approved to allow it to proceed to the production environment.

The tag name is defined in the [azure-pipelines-release.yml](./azure-pipelines-release.yml).

#### Publishing new versions manually without release-please
### Publishing new versions manually without release-please

For canary release the naming convention is `x.y.z-canary-[gitcommithash]`. Running `yarn publish` should ask for version number too, but a `version` property in `package.json` sets the version number.
For canary release the naming convention is `x.y.z-canary-[gitcommithash]`. Running `pnpm publish` should ask for version number too, but a `version` property in `package.json` sets the version number.

1. Build package with `yarn build`
2. Publish package `yarn publish`
1. Build package with `pnpm build`
2. Publish package `pnpm publish`

**Note:** A local tarball of built package can be created with `yarn pack`. Just remember to build first.
**Note:** A local tarball of built package can be created with `pnpm pack`. Just remember to build first.

**Note:** There is an a known issue with publishing using Windows environment. If you have a Windows machine use Docker container to publish the package.An Apollo client linked to a graphql endpoint with a supported schema (headless CMS) must be provided in the `apolloClient` field of the `config` object.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

## Known issues

- Jest has difficulties loading this library. When this library is required in a test file, it's possible that some imports are cjs and some are esm. These two variants do not share a react context which can result in `useConfig` calls that return an empty config object even though `<ConfigProvider>` is declared correctly. I.e. `<ConfigProvider>` sets values for `context1` and `useConfig` reads `context2`.
- Some of the built packages created with `yarn build` does some issues with some types. This leads to a situation where the application that uses the library cannot read all the exported types. Especially the exported enums inside a built package might be handled incorrectly (https://github.com/rollup/rollup/issues/4291), but there are other type related issues also, but not on every built package.
- Some of the built packages created with `pnpm build` does some issues with some types. This leads to a situation where the application that uses the library cannot read all the exported types. Especially the exported enums inside a built package might be handled incorrectly (https://github.com/rollup/rollup/issues/4291), but there are other type related issues also, but not on every built package.
Comment thread
Riippi marked this conversation as resolved.
Outdated
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

## Contributing

Expand Down
3 changes: 1 addition & 2 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import js from '@eslint/js';
import stylisticPlugin from '@stylistic/eslint-plugin';
import tseslint from 'typescript-eslint';
import tsParser from '@typescript-eslint/parser';
import importPlugin from 'eslint-plugin-import-x';
import jsxA11yPlugin from 'eslint-plugin-jsx-a11y';
import prettierPlugin from 'eslint-plugin-prettier';
Expand Down Expand Up @@ -144,7 +143,7 @@ export default [
{
files,
languageOptions: {
parser: tsParser,
parser: tseslint.parser,
parserOptions: {
ecmaVersion: 2018,
ecmaFeatures: { jsx: true },
Expand Down
Loading
Loading