Skip to content

Commit b5fe044

Browse files
committed
feat: add comprehensive npm release configuration
- Add automated GitHub Actions release workflow - Enhance CI workflow to run on master branch - Add release readiness check script - Improve package.json with better keywords and release scripts - Add comprehensive release documentation (RELEASE.md) - Update .npmignore for better package optimization - Fix ESLint configuration to exclude scripts directory
1 parent f7f4571 commit b5fe044

File tree

6 files changed

+344
-3
lines changed

6 files changed

+344
-3
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ on:
33
push:
44
branches:
55
- main
6+
- master
67
pull_request:
78
branches:
89
- main
10+
- master
911

1012
jobs:
1113
lint:

.github/workflows/release.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: Release
2+
on:
3+
push:
4+
branches:
5+
- master
6+
workflow_dispatch:
7+
8+
jobs:
9+
release:
10+
runs-on: ubuntu-latest
11+
if: "!contains(github.event.head_commit.message, 'chore: release')"
12+
steps:
13+
- name: Checkout
14+
uses: actions/checkout@v4
15+
with:
16+
fetch-depth: 0
17+
token: ${{ secrets.GITHUB_TOKEN }}
18+
19+
- name: Setup
20+
uses: ./.github/actions/setup
21+
22+
- name: Lint files
23+
run: yarn lint
24+
25+
- name: Typecheck files
26+
run: yarn typecheck
27+
28+
- name: Run unit tests
29+
run: yarn test --maxWorkers=2 --coverage
30+
31+
- name: Build package
32+
run: yarn prepack
33+
34+
- name: Setup Git user
35+
run: |
36+
git config --global user.name 'github-actions[bot]'
37+
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
38+
39+
- name: Setup NPM token
40+
run: echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > ~/.npmrc
41+
42+
- name: Release
43+
run: yarn release --ci
44+
env:
45+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
46+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

RELEASE.md

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# Release Guide
2+
3+
This document explains how to release new versions of `rn-firebase-chat` to npm.
4+
5+
## Prerequisites
6+
7+
1. **NPM Account**: You need to be logged into npm with publish permissions
8+
```bash
9+
npm whoami # Check if logged in
10+
npm login # Login if needed
11+
```
12+
13+
2. **Repository Access**: You need write access to the GitHub repository
14+
15+
3. **Clean Working Directory**: Ensure no uncommitted changes
16+
```bash
17+
git status # Should show "working tree clean"
18+
```
19+
20+
## Release Process
21+
22+
### Automated Release (Recommended)
23+
24+
The package uses `release-it` for automated releases with conventional changelog generation.
25+
26+
#### For Patch Releases (Bug Fixes)
27+
```bash
28+
yarn release
29+
```
30+
31+
#### For Minor Releases (New Features)
32+
```bash
33+
yarn release minor
34+
```
35+
36+
#### For Major Releases (Breaking Changes)
37+
```bash
38+
yarn release major
39+
```
40+
41+
#### Dry Run (Test Without Publishing)
42+
```bash
43+
yarn release:dry
44+
```
45+
46+
### Manual Release Steps
47+
48+
If you prefer manual control:
49+
50+
1. **Update Version**
51+
```bash
52+
npm version patch # or minor, major
53+
```
54+
55+
2. **Build the Package**
56+
```bash
57+
yarn prepack
58+
```
59+
60+
3. **Run Tests**
61+
```bash
62+
yarn test
63+
yarn lint
64+
yarn typecheck
65+
```
66+
67+
4. **Publish to npm**
68+
```bash
69+
npm publish
70+
```
71+
72+
5. **Push Changes**
73+
```bash
74+
git push origin master --tags
75+
```
76+
77+
## GitHub Actions (CI/CD)
78+
79+
The repository includes automated workflows:
80+
81+
- **CI Workflow** (`ci.yml`): Runs on every push/PR to master branch
82+
- Linting
83+
- Type checking
84+
- Unit tests
85+
- Build verification
86+
87+
- **Release Workflow** (`release.yml`): Automated releases on master branch
88+
- Runs full CI checks
89+
- Publishes to npm
90+
- Creates GitHub releases
91+
- Updates changelog
92+
93+
### Setting up Automated Releases
94+
95+
To enable automated releases via GitHub Actions, add these secrets to your repository:
96+
97+
1. Go to GitHub repository → Settings → Secrets and variables → Actions
98+
2. Add the following secrets:
99+
- `NPM_TOKEN`: Your npm automation token
100+
- `GITHUB_TOKEN`: Automatically provided by GitHub
101+
102+
#### Creating NPM Token
103+
104+
1. Go to [npm.com](https://www.npmjs.com) → Profile → Access Tokens
105+
2. Generate New Token → Automation
106+
3. Copy the token and add it to GitHub secrets
107+
108+
## Pre-Release Checklist
109+
110+
- [ ] All tests pass (`yarn test`)
111+
- [ ] No linting errors (`yarn lint`)
112+
- [ ] No TypeScript errors (`yarn typecheck`)
113+
- [ ] Build succeeds (`yarn prepack`)
114+
- [ ] Update README if needed
115+
- [ ] Update CHANGELOG if using manual process
116+
- [ ] Working tree is clean (`git status`)
117+
118+
## Post-Release Checklist
119+
120+
- [ ] Verify package published to npm: https://www.npmjs.com/package/rn-firebase-chat
121+
- [ ] Check GitHub release created: https://github.com/saigontechnology/rn-firebase-chat/releases
122+
- [ ] Test installation in a fresh project
123+
- [ ] Update example app if needed
124+
125+
## Troubleshooting
126+
127+
### NPM Publish Fails
128+
- Check if you're logged in: `npm whoami`
129+
- Verify package name isn't taken
130+
- Check npm registry: `npm config get registry`
131+
132+
### Version Already Exists
133+
- Check latest version: `npm view rn-firebase-chat version`
134+
- Use correct version bump: patch/minor/major
135+
136+
### Git Push Fails
137+
- Ensure you have push permissions
138+
- Check if branch is protected
139+
- Verify remote URL: `git remote -v`
140+
141+
## Semantic Versioning
142+
143+
This package follows [Semantic Versioning (SemVer)](https://semver.org/):
144+
145+
- **PATCH** (x.x.X): Bug fixes, documentation updates
146+
- **MINOR** (x.X.x): New features, backward compatible
147+
- **MAJOR** (X.x.x): Breaking changes, API changes
148+
149+
## Conventional Commits
150+
151+
Use conventional commit messages for automatic changelog generation:
152+
153+
- `feat:` - New features (minor version bump)
154+
- `fix:` - Bug fixes (patch version bump)
155+
- `docs:` - Documentation changes
156+
- `style:` - Code style changes
157+
- `refactor:` - Code refactoring
158+
- `test:` - Test changes
159+
- `chore:` - Maintenance tasks
160+
- `BREAKING CHANGE:` - Breaking changes (major version bump)

eslint.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export default [
99
js.configs.recommended,
1010
{
1111
files: ['**/*.{js,jsx,ts,tsx}'],
12-
ignores: ['node_modules/', 'lib/', 'example/'],
12+
ignores: ['node_modules/', 'lib/', 'example/', 'scripts/'],
1313
languageOptions: {
1414
parser: tsParser,
1515
parserOptions: {

package.json

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,25 @@
2121
"prepack": "bob build && yarn clean:maps",
2222
"prepare": "bob build && yarn clean:maps",
2323
"release": "release-it",
24+
"release:dry": "release-it --dry-run",
25+
"release:ci": "release-it --ci",
26+
"release:check": "node scripts/check-release.js",
2427
"example": "yarn --cwd example",
2528
"bootstrap": "yarn example && yarn install && yarn example pods"
2629
},
2730
"keywords": [
2831
"react-native",
2932
"ios",
30-
"android"
33+
"android",
34+
"chat",
35+
"firebase",
36+
"firestore",
37+
"messaging",
38+
"real-time",
39+
"conversation",
40+
"ui",
41+
"components",
42+
"typescript"
3143
],
3244
"repository": "https://github.com/saigontechnology/rn-firebase-chat",
3345
"author": "BaoNH <[email protected]> (https://github.com/baonguyenhsts)",
@@ -142,7 +154,8 @@
142154
"eslintIgnore": [
143155
"node_modules/",
144156
"lib/",
145-
"example/"
157+
"example/",
158+
"scripts/"
146159
],
147160
"prettier": {
148161
"quoteProps": "consistent",

scripts/check-release.js

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
#!/usr/bin/env node
2+
3+
const fs = require('fs');
4+
const path = require('path');
5+
const { execSync } = require('child_process');
6+
7+
console.log('🔍 Checking package release readiness...\n');
8+
9+
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
10+
let allChecks = true;
11+
12+
// Check 1: Required fields
13+
console.log('📋 Checking required package.json fields...');
14+
const requiredFields = ['name', 'version', 'description', 'main', 'types', 'repository', 'license'];
15+
requiredFields.forEach(field => {
16+
if (packageJson[field]) {
17+
console.log(` ✅ ${field}: ${packageJson[field]}`);
18+
} else {
19+
console.log(` ❌ ${field}: missing`);
20+
allChecks = false;
21+
}
22+
});
23+
24+
// Check 2: Files array
25+
console.log('\n📁 Checking files configuration...');
26+
if (packageJson.files && packageJson.files.length > 0) {
27+
console.log(` ✅ files: ${packageJson.files.join(', ')}`);
28+
29+
// Check if specified files exist
30+
packageJson.files.forEach(file => {
31+
if (fs.existsSync(file)) {
32+
console.log(` ✅ ${file} exists`);
33+
} else {
34+
console.log(` ⚠️ ${file} does not exist yet (will be created during build)`);
35+
}
36+
});
37+
} else {
38+
console.log(' ❌ files: not specified');
39+
allChecks = false;
40+
}
41+
42+
// Check 3: Build output
43+
console.log('\n🔨 Checking build configuration...');
44+
if (packageJson['react-native-builder-bob']) {
45+
console.log(' ✅ React Native Builder Bob configured');
46+
const bobConfig = packageJson['react-native-builder-bob'];
47+
console.log(` Source: ${bobConfig.source}`);
48+
console.log(` Output: ${bobConfig.output}`);
49+
console.log(` Targets: ${bobConfig.targets.join(', ')}`);
50+
} else {
51+
console.log(' ❌ React Native Builder Bob not configured');
52+
allChecks = false;
53+
}
54+
55+
// Check 4: Scripts
56+
console.log('\n⚙️ Checking required scripts...');
57+
const requiredScripts = ['prepack', 'prepare'];
58+
requiredScripts.forEach(script => {
59+
if (packageJson.scripts[script]) {
60+
console.log(` ✅ ${script}: ${packageJson.scripts[script]}`);
61+
} else {
62+
console.log(` ❌ ${script}: missing`);
63+
allChecks = false;
64+
}
65+
});
66+
67+
// Check 5: Git status
68+
console.log('\n🔄 Checking git status...');
69+
try {
70+
const gitStatus = execSync('git status --porcelain', { encoding: 'utf8' });
71+
if (gitStatus.trim() === '') {
72+
console.log(' ✅ Working directory is clean');
73+
} else {
74+
console.log(' ⚠️ Working directory has uncommitted changes:');
75+
console.log(gitStatus);
76+
}
77+
} catch (error) {
78+
console.log(' ❌ Git status check failed');
79+
allChecks = false;
80+
}
81+
82+
// Check 6: NPM login
83+
console.log('\n👤 Checking npm authentication...');
84+
try {
85+
const npmUser = execSync('npm whoami 2>/dev/null', { encoding: 'utf8' }).trim();
86+
console.log(` ✅ Logged in as: ${npmUser}`);
87+
} catch (error) {
88+
console.log(' ❌ Not logged into npm');
89+
console.log(' Run: npm login');
90+
allChecks = false;
91+
}
92+
93+
// Check 7: Dependencies
94+
console.log('\n📦 Checking dependencies...');
95+
if (packageJson.peerDependencies) {
96+
console.log(` ✅ Peer dependencies: ${Object.keys(packageJson.peerDependencies).join(', ')}`);
97+
} else {
98+
console.log(' ⚠️ No peer dependencies specified');
99+
}
100+
101+
// Check 8: TypeScript
102+
console.log('\n📝 Checking TypeScript configuration...');
103+
if (fs.existsSync('tsconfig.json') && fs.existsSync('tsconfig.build.json')) {
104+
console.log(' ✅ TypeScript configuration files exist');
105+
} else {
106+
console.log(' ❌ Missing TypeScript configuration');
107+
allChecks = false;
108+
}
109+
110+
// Final result
111+
console.log('\n' + '='.repeat(50));
112+
if (allChecks) {
113+
console.log('🎉 Package is ready for release!');
114+
console.log('\nNext steps:');
115+
console.log(' • Run: yarn release:dry (to test)');
116+
console.log(' • Run: yarn release (to publish)');
117+
} else {
118+
console.log('⚠️ Some issues need to be addressed before release');
119+
}
120+
console.log('='.repeat(50));

0 commit comments

Comments
 (0)