Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
39 changes: 30 additions & 9 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,36 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- name: Use Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v7
with:
node-version: 20.x
- name: Install dependencies
uses: borales/actions-yarn@v4
node-version: 24.x
cache: yarn
- run: corepack enable
- run: yarn install --frozen-lockfile
- run: make verify

react-compatibility:
runs-on: ubuntu-latest
strategy:
matrix:
react: [18, 19]

steps:
- uses: actions/checkout@v7
- name: Use Node.js
uses: actions/setup-node@v7
with:
cmd: install # will run `yarn install` command
- run: make lint
- run: make test
- run: make clean build
node-version: 24.x
cache: yarn
- run: corepack enable
- run: yarn install --frozen-lockfile
- name: Install React compatibility version
run: >-
yarn add --dev --ignore-scripts --no-lockfile
react@${{ matrix.react }}
react-dom@${{ matrix.react }}
@types/react@${{ matrix.react }}
@types/react-dom@${{ matrix.react }}
- run: make typecheck test
23 changes: 15 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@ NODE = node --harmony
BABEL = ./node_modules/.bin/babel
MOCHA = node --harmony node_modules/.bin/mocha --reporter spec --require test/setup.js --compilers js:babel-core/register
ESLINT = node_modules/.bin/eslint
JEST = node_modules/.bin/jest
JEST = node_modules/.bin/jest --no-watchman
ROLLUP = node_modules/.bin/rollup
TSC = node_modules/.bin/tsc
PRETTIER = node_modules/.bin/prettier
STORYBOOK_TO_PAGES = node_modules/.bin/storybook-to-ghpages
NPM_ENV_VARS = npm_config_registry=https://registry.npmjs.org
NPM = $(NPM_ENV_VARS) npm
XYZ = $(NPM_ENV_VARS) node_modules/.bin/xyz --repo git@github.com:plaid/react-plaid-link.git
STORYBOOK = node_modules/.bin/start-storybook
RELEASE_BRANCH = $(shell git rev-parse --abbrev-ref HEAD)

SRC_FILES = $(shell find src -name '*.js|*.tsx|*.ts' | sort)

Expand Down Expand Up @@ -45,6 +42,16 @@ test-watch: export BABEL_ENV=testing
test-watch:
@$(JEST) --watch


.PHONY: typecheck
typecheck:
@$(TSC) --noEmit


.PHONY: verify
verify: lint typecheck test build
@$(MAKE) check-import

.PHONY: lint-fix
lint-fix:
@$(ESLINT) --fix '{src,examples}/**/*.{ts,tsx,js,jsx}'
Expand Down Expand Up @@ -75,6 +82,6 @@ storybook-deploy:
$(STORYBOOK_TO_PAGES)


.PHONY: release-major release-minor release-patch release-premajor release-preminor release-prepatch release-prerelease
release-major release-minor release-patch release-premajor release-preminor release-prepatch release-prerelease: build
@$(XYZ) --increment $(@:release-%=%) --branch $(RELEASE_BRANCH) --prerelease-label beta
.PHONY: release
release: verify
@./scripts/release
68 changes: 21 additions & 47 deletions PUBLISH.md
Original file line number Diff line number Diff line change
@@ -1,55 +1,29 @@
## Publishing

**We use the `xyz` NPM package to simplify releases. This library uses a feature that is available in Bash 4 or beyond, but latest versions of macOS
ship with an older version of Bash. If you run into issues with `xyz`, use `brew install bash` to install a newer verison of Bash.**
Releases are prepared on a branch and published from the merge commit on
`master`.

If you run into any `npm` package versioning issues, make sure you run `make setup` rather than calling `npm install` directly.
1. Create a release branch from the latest `master`.
2. Move the `Unreleased` changelog entries under the new version heading.
3. Update `package.json` without creating a tag:

1. Create a branch to stage the release, for example `release-3.4.5` (Read [semver](https://semver.org/) to determine what type of version bump to use.)
```bash
yarn version --new-version <version> --no-git-tag-version
```

```
git checkout -b release-3.4.5
git fetch
git reset --hard origin/master
```
4. Open and merge the release PR after CI passes.
5. Check out the updated `master`, confirm it matches `origin/master`, and
authenticate with npm.
6. Run:

2. Run `make storybook` and verify that there are no regressions with Link.
```bash
make release
```

3. Update `CHANGELOG.md` with changes that will be included in the release, commit and push to the release branch. To help confirm the changes
that will be included in the release, consider using GitHub's compare feature: https://github.com/plaid/react-plaid-link/compare/v3.4.0...master
(replace `v3.4.0` with the last published version).
The release command runs lint, type checking, tests, and all builds before
publishing. It publishes the version already recorded in `package.json`, then
creates and pushes the annotated `v<version>` tag.

4. When ready, publish the new version from the branch before merging

```
make release-(patch|minor|major)
```

5. Merge the branch

#### **If the `make` command errors out with an authentication issue**

If `make release-*` from above errors out with an authentication issue,
you may need to `npm login` or otherwise manually set up your `~/.npmrc` file to
make sure you have access to publish to npm.

#### (dangerous) Manually publish an already-built package to npm

If you've set up your npm authentication as described above, but are still seeing authentication issues when running `make release-*`, you can
directly publish a **built** package to the npm registry using the manual commands below. You should **only** publish the package manually using these steps
if the build steps of the `make release-*` command were **successful**. If the build steps did not succeeed, running these commands could publish an unbuilt
version of the package, which would lead to a broken release.

1. Publish already-built package to npm manually

```bash
npm --registry=https://registry.npmjs.com publish
```

2. Push tags manually

```bash
git push --follow-tags
```

Also, under [github releases page](https://github.com/plaid/react-plaid-link/releases), draft a new release corresponding to the tag of the latest version.
If npm publication succeeds but tagging fails, rerun `make release`. The
release script detects the published npm version and resumes with the missing
tag instead of attempting to republish.
26 changes: 13 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,17 @@
"@storybook/preset-typescript": "^2.1.0",
"@storybook/react": "^5.3.17",
"@storybook/storybook-deployer": "^2.8.3",
"@testing-library/react": "^12.1.4",
"@testing-library/react-hooks": "^7.0.2",
"@testing-library/dom": "10.4.1",
"@testing-library/react": "16.3.2",
"@types/jest": "^27.4.1",
"@types/react": "^17.0.9",
"@types/react-dom": "^17.0.6",
"@typescript-eslint/eslint-plugin": "^2.24.0",
"@typescript-eslint/parser": "^2.24.0",
"@wessberg/rollup-plugin-ts": "^1.2.21",
"@types/react": "19.2.17",
"@types/react-dom": "19.2.3",
"@typescript-eslint/eslint-plugin": "5.62.0",
"@typescript-eslint/parser": "5.62.0",
"babel-loader": "^8.0.6",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-typescript-to-proptypes": "^1.3.2",
"eslint": "6.6.0",
"eslint": "7.32.0",
"eslint-config-airbnb": "18.0.1",
"eslint-config-prettier": "^6.10.0",
"eslint-plugin-import": "^2.18.2",
Expand All @@ -89,19 +88,20 @@
"jest": "^27.5.1",
"mocha": "2.3.x",
"prettier": "^1.19.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react": "19.2.8",
"react-dom": "19.2.8",
"react-tools": "0.13.x",
"rollup": "^1.27.0",
"rollup": "2.80.0",
"rollup-plugin-babel": "^4.3.3",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-replace": "^2.2.0",
"rollup-plugin-terser": "^5.1.2",
"rollup-plugin-typescript2": "0.37.0",
"sinon": "1.17.x",
"ts-loader": "^6.2.1",
"typescript": "^3.8.3",
"xyz": "^4.0.x"
"tslib": "^2.8.1",
"typescript": "5.9.3"
},
"tags": [
"react",
Expand Down
14 changes: 10 additions & 4 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import commonjs from 'rollup-plugin-commonjs';
import resolve from 'rollup-plugin-node-resolve';
import { terser } from 'rollup-plugin-terser';
import replace from 'rollup-plugin-replace';
import ts from '@wessberg/rollup-plugin-ts';
import typescript from 'rollup-plugin-typescript2';
import pkg from './package.json';

export default [
Expand All @@ -15,8 +15,8 @@ export default [
{ file: pkg.module, format: 'es' },
],
plugins: [
ts(),
resolve(),
typescript({ clean: true, tsconfig: 'tsconfig.build.json' }),
babel({
extensions: ['.ts', '.js', '.tsx', '.jsx'],
}),
Expand All @@ -38,8 +38,11 @@ export default [
},
],
plugins: [
ts(),
resolve(),
typescript({
tsconfig: 'tsconfig.build.json',
tsconfigOverride: { compilerOptions: { declaration: false } },
}),
babel({
extensions: ['.ts', '.js', '.tsx', '.jsx'],
}),
Expand All @@ -61,8 +64,11 @@ export default [
},
],
plugins: [
ts(),
resolve(),
typescript({
tsconfig: 'tsconfig.build.json',
tsconfigOverride: { compilerOptions: { declaration: false } },
}),
babel({
extensions: ['.ts', '.js', '.tsx', '.jsx'],
}),
Expand Down
81 changes: 81 additions & 0 deletions scripts/release
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/bin/sh

set -eu

registry=https://registry.npmjs.org

abort() {
printf '%s\n' "$1" >&2
exit 1
}

branch=$(git rev-parse --abbrev-ref HEAD)
[ "$branch" = master ] || abort "Releases must run from master."
[ -z "$(git status --porcelain)" ] || abort "The working tree must be clean."

git fetch origin master --tags

head_commit=$(git rev-parse HEAD)
remote_commit=$(git rev-parse origin/master)
[ "$head_commit" = "$remote_commit" ] ||
abort "Local master must match origin/master."

name=$(node -p "require('./package.json').name")
version=$(node -p "require('./package.json').version")
tag="v$version"

grep -F "## $version" CHANGELOG.md >/dev/null ||
abort "CHANGELOG.md must contain a section for $version."

published=false
if published_version=$(npm view "$name@$version" version --registry="$registry" 2>/dev/null); then
[ "$published_version" = "$version" ] ||
abort "Unexpected npm version response: $published_version"
published=true
elif ! npm view "$name" version --registry="$registry" >/dev/null 2>&1; then
abort "Unable to query $name on npm."
fi

tag_exists=false
if tag_commit=$(git rev-parse -q --verify "refs/tags/$tag^{commit}"); then
[ "$tag_commit" = "$head_commit" ] ||
abort "$tag already points to a different commit."
tag_exists=true
fi

remote_tag_exists=false
if [ -n "$(git ls-remote --tags origin "refs/tags/$tag")" ]; then
remote_tag_exists=true
fi

if [ "$published" = true ] && [ "$remote_tag_exists" = true ]; then
printf '%s\n' "$name@$version is already published and tagged."
exit 0
fi

printf 'Release %s@%s from %s? Type "release" to continue: ' \
"$name" "$version" "$head_commit"
read -r confirmation
[ "$confirmation" = release ] || abort "Release cancelled."

if [ "$published" = false ]; then
case "$version" in
*-*)
prerelease=${version#*-}
dist_tag=${prerelease%%.*}
npm publish --registry="$registry" --tag "$dist_tag"
;;
*)
npm publish --registry="$registry"
;;
esac
else
printf '%s\n' "$name@$version is already on npm; continuing with the tag."
fi

if [ "$tag_exists" = false ]; then
git tag --annotate "$tag" --message "Version $version"
fi

git push origin "refs/tags/$tag"
printf 'Released %s@%s and %s.\n' "$name" "$version" "$tag"
4 changes: 3 additions & 1 deletion src/PlaidEmbeddedLink.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useRef, useMemo } from 'react';
import React from 'react';
import useScript from './react-script-hook';

import { PLAID_LINK_STABLE_URL } from './constants';
Expand All @@ -7,6 +7,8 @@ import {
PlaidLinkOptionsWithLinkToken,
} from './types';

const { useEffect, useMemo, useRef } = React;

export const PlaidEmbeddedLink = (props: PlaidEmbeddedLinkPropTypes) => {
const {
style,
Expand Down
Loading