@@ -14,26 +14,24 @@ jobs:
1414 release-please :
1515 runs-on : ubuntu-latest
1616 outputs :
17- main-release-created : ${{ steps.release.outputs.release_created }}
18- main-tag-name : ${{ steps.release.outputs.tag_name }}
19- eslint-plugin-release-created : ${{ steps.release.outputs['eslint-plugin-codekeeper--release_created'] }}
20- eslint-plugin-tag-name : ${{ steps.release.outputs['eslint-plugin-codekeeper--tag_name'] }}
17+ release-created : ${{ steps.release.outputs.release_created }}
18+ tag-name : ${{ steps.release.outputs.tag_name }}
19+ version : ${{ steps.release.outputs.version }}
2120
2221 steps :
2322 - name : Release Please
2423 id : release
2524 uses : googleapis/release-please-action@v4
2625 with :
2726 token : ${{ secrets.GITHUB_TOKEN }}
28- config-file : .github/release-please-config.json
29- manifest-file : .github/.release-please-manifest.json
30- skip-labeling : true
3127 release-type : node
28+ package-name : codekeeper-guardrails
29+ skip-labeling : true
3230
3331 publish-main-release :
3432 runs-on : ubuntu-latest
3533 needs : release-please
36- if : needs.release-please.outputs.main- release-created == 'true'
34+ if : needs.release-please.outputs.release-created == 'true'
3735
3836 steps :
3937 - name : Checkout
@@ -78,248 +76,123 @@ jobs:
7876 if [ ! -d "scripts" ]; then
7977 mkdir -p scripts
8078 fi
79+ cp -r scripts/validation scripts/
8180
82- cp -r validation/ scripts/
83-
84- # Install git hooks if lefthook.yml exists
85- if [ -f "lefthook.yml" ] && command -v lefthook >/dev/null 2>&1; then
86- echo "Installing git hooks with lefthook..."
87- lefthook install
88- fi
89-
90- echo "✅ CodeKeeper installed successfully!"
91- echo "📋 Available validation scripts:"
92- ls scripts/validation/
81+ echo "✅ CodeKeeper validation scripts installed successfully!"
82+ echo "📚 See examples/ directory for usage examples"
9383 EOF
9484
9585 chmod +x release-assets/install-codekeeper.sh
9686
87+ # Include key documentation
88+ cp README.md release-assets/
89+ cp LICENSE release-assets/ || echo "No LICENSE file found"
90+ cp CHANGELOG.md release-assets/ || echo "No CHANGELOG file found"
91+
9792 # Create archive
98- tar -czf codekeeper-${{ needs.release-please.outputs.main- tag-name }}.tar.gz -C release-assets .
93+ tar -czf codekeeper-${{ needs.release-please.outputs.tag-name }}.tar.gz -C release-assets .
9994
100- echo "📁 Release assets created"
95+ echo "✅ Release assets created successfully "
10196
10297 - name : Upload Release Assets
103- uses : actions/upload-artifact@v4
104- with :
105- name : release-assets
106- path : release-assets/
107-
108- - name : Update GitHub Release
10998 uses : actions/github-script@v7
11099 with :
111100 script : |
112101 const fs = require('fs');
113102 const path = require('path');
114103
115- // Get the release
116- const { data: release } = await github.rest.repos.getReleaseByTag({
117- owner: context.repo.owner,
118- repo: context.repo.repo,
119- tag: '${{ needs.release-please.outputs.main-tag-name }}'
120- });
121-
122- // Upload the tarball
123- if (fs.existsSync('codekeeper-${{ needs.release-please.outputs.main-tag-name }}.tar.gz')) {
124- const assetData = fs.readFileSync('codekeeper-${{ needs.release-please.outputs.main-tag-name }}.tar.gz');
104+ try {
105+ // Find the release created by release-please
106+ const releases = await github.rest.repos.listReleases({
107+ owner: context.repo.owner,
108+ repo: context.repo.repo,
109+ per_page: 5
110+ });
111+
112+ const targetRelease = releases.data.find(release =>
113+ release.tag_name === '${{ needs.release-please.outputs.tag-name }}'
114+ );
115+
116+ if (!targetRelease) {
117+ console.log('⚠️ Release not found yet, it may still be creating...');
118+ return;
119+ }
120+
121+ console.log(`📎 Uploading assets to release ${targetRelease.tag_name}...`);
122+
123+ // Upload the tar.gz archive
124+ if (fs.existsSync('codekeeper-${{ needs.release-please.outputs.tag-name }}.tar.gz')) {
125+ const assetData = fs.readFileSync('codekeeper-${{ needs.release-please.outputs.tag-name }}.tar.gz');
126+
127+ await github.rest.repos.uploadReleaseAsset({
128+ owner: context.repo.owner,
129+ repo: context.repo.repo,
130+ release_id: targetRelease.id,
131+ name: 'codekeeper-${{ needs.release-please.outputs.tag-name }}.tar.gz',
132+ data: assetData,
133+ headers: {
134+ 'content-type': 'application/gzip',
135+ 'content-length': assetData.length
136+ }
137+ });
138+
139+ console.log('✅ Archive uploaded successfully');
140+ }
141+
142+ // Update release body with installation instructions
143+ const installInstructions = `
144+
145+ ## 📦 Installation
146+
147+ Download and extract the release archive:
125148
126- await github.rest.repos.uploadReleaseAsset({
149+ \`\`\`bash
150+ curl -L https://github.com/${{ github.repository }}/releases/download/${{ needs.release-please.outputs.tag-name }}/codekeeper-${{ needs.release-please.outputs.tag-name }}.tar.gz | tar -xz
151+ \`\`\`
152+
153+ Or run the installation script:
154+
155+ \`\`\`bash
156+ ./install-codekeeper.sh
157+ \`\`\`
158+ `;
159+
160+ await github.rest.repos.updateRelease({
127161 owner: context.repo.owner,
128162 repo: context.repo.repo,
129- release_id: release.id,
130- name: 'codekeeper-${{ needs.release-please.outputs.main-tag-name }}.tar.gz',
131- data: assetData,
132- headers: {
133- 'content-type': 'application/gzip',
134- 'content-length': assetData.length
135- }
163+ release_id: targetRelease.id,
164+ body: targetRelease.body + installInstructions
136165 });
166+
167+ console.log('✅ Release updated with installation instructions');
168+ } catch (error) {
169+ console.error('Error uploading release assets:', error);
170+ core.setFailed(error.message);
137171 }
138-
139- // Update release body with installation instructions
140- const releaseBody = release.body + `
141-
142- ## 🚀 Quick Installation
143-
144- ### Option 1: Download and Extract
145- \`\`\`bash
146- curl -L https://github.com/${{ github.repository }}/releases/download/${{ needs.release-please.outputs.main-tag-name }}/codekeeper-${{ needs.release-please.outputs.main-tag-name }}.tar.gz | tar -xz
147- \`\`\`
148-
149- ### Option 2: Copy Individual Scripts
150- Copy the validation scripts from \`scripts/validation/\` to your project and set up git hooks with lefthook.
151-
152- ### Option 3: Use ESLint Plugin
153- \`\`\`bash
154- npm install @thedaviddias/eslint-plugin-codekeeper
155- \`\`\`
156-
157- ## 📋 What's Included
158- - ✅ **Validation Scripts**: Copy-paste ready validation scripts
159- - ✅ **Examples**: Real-world integration examples
160- - ✅ **Git Hooks**: Pre-configured lefthook integration
161- - ✅ **ESLint Plugin**: IDE integration available separately
162-
163- ---
164-
165- **🛡️ CodeKeeper**: AI Development Guardrails for React/Next.js Projects`;
166-
167- await github.rest.repos.updateRelease({
168- owner: context.repo.owner,
169- repo: context.repo.repo,
170- release_id: release.id,
171- body: releaseBody
172- });
173-
174- publish-eslint-plugin :
175- runs-on : ubuntu-latest
176- needs : release-please
177- if : needs.release-please.outputs.eslint-plugin-release-created == 'true'
178- permissions :
179- contents : read
180- packages : write
181-
182- steps :
183- - name : Checkout
184- uses : actions/checkout@v4
185-
186- - name : Setup Node.js
187- uses : ./.github/actions/setup-node
188- with :
189- install-dependencies : ' false'
190-
191- - name : Sync and validate ESLint plugin
192- run : |
193- echo "🔄 Syncing validators to ESLint plugin..."
194- cp -r lib/ eslint-plugin-codekeeper/
195-
196- echo "🧪 Validating ESLint plugin..."
197-
198- # Test plugin structure and functionality
199- cd eslint-plugin-codekeeper
200- node -e "
201- const plugin = require('./index.js');
202- if (!plugin.meta || !plugin.rules || !plugin.configs) {
203- console.log('❌ Plugin structure invalid');
204- process.exit(1);
205- }
206- console.log('✅ Plugin structure valid');
207- "
208- cd ..
209-
210- # Test ESLint rules functionality
211- node test-validation/test-eslint-plugin.js
212-
213- echo "✅ ESLint plugin validation complete"
214-
215- - name : Authenticate to GitHub Packages
216- run : echo "//npm.pkg.github.com/:_authToken=${{ secrets.GITHUB_TOKEN }}" >> ~/.npmrc
217-
218- - name : Publish ESLint plugin to GitHub Packages
219- working-directory : ./eslint-plugin-codekeeper
220- run : |
221- echo "📦 Publishing ESLint plugin to GitHub Packages..."
222- npm publish
223- echo "✅ Published to GitHub Packages"
224- env :
225- NODE_AUTH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
226-
227- - name : Create ESLint Plugin GitHub Release
228- uses : actions/github-script@v7
229- with :
230- script : |
231- // Create a GitHub release for the ESLint plugin
232- const { data: release } = await github.rest.repos.createRelease({
233- owner: context.repo.owner,
234- repo: context.repo.repo,
235- tag_name: '${{ needs.release-please.outputs.eslint-plugin-tag-name }}',
236- name: 'ESLint Plugin ${{ needs.release-please.outputs.eslint-plugin-tag-name }}',
237- body: `## 🔌 ESLint Plugin CodeKeeper Release
238-
239- This release contains the ESLint plugin for CodeKeeper validation rules.
240-
241- ### 📦 Installation
242- \`\`\`bash
243- npm install --save-dev @thedaviddias/eslint-plugin-codekeeper
244- \`\`\`
245-
246- ### ⚙️ Configuration
247- \`\`\`javascript
248- // .eslintrc.js
249- module.exports = {
250- plugins: ['@thedaviddias/codekeeper'],
251- extends: ['plugin:@thedaviddias/codekeeper/recommended']
252- };
253- \`\`\`
254-
255- ### 🛡️ Rules Included
256- - **\`no-unsafe-as-casts\`**: Prevents dangerous TypeScript \`as\` casts
257- - **\`no-barrel-files\`**: Warns against barrel files that harm tree-shaking
258- - **\`max-file-complexity\`**: Enforces file complexity limits
259- - **\`require-jsdoc\`**: Requires JSDoc comments for functions and classes
260-
261- ### 🎯 Available Configurations
262- - **\`recommended\`**: Balanced rules for most projects
263- - **\`strict\`**: Stricter rules for high-quality codebases
264- - **\`react\`**: Optimized for React projects
265-
266- ### 📋 Usage Examples
267- \`\`\`javascript
268- // Recommended config
269- extends: ['plugin:@thedaviddias/codekeeper/recommended']
270172
271- // Strict config
272- extends: ['plugin:@thedaviddias/codekeeper/strict']
273-
274- // React-specific config
275- extends: ['plugin:@thedaviddias/codekeeper/react']
276- \`\`\`
277-
278- ---
279-
280- **🔗 Links:**
281- - [Main CodeKeeper Project](https://github.com/${{ github.repository }})
282- - [GitHub Package](https://github.com/${{ github.repository }}/packages/)
283- - [Documentation](https://github.com/${{ github.repository }}#readme)
284-
285- **🛡️ CodeKeeper**: AI Development Guardrails for React/Next.js Projects`,
286- draft: false,
287- prerelease: false
288- });
289-
290- console.log('✅ ESLint plugin GitHub release created');
291-
292- notify-releases :
173+ notify-release :
174+ name : Release Notification
293175 runs-on : ubuntu-latest
294- needs : [release-please, publish-main-release, publish-eslint-plugin ]
295- if : always() && ( needs.release-please.outputs.main- release-created == 'true' || needs.release-please.outputs.eslint-plugin-release-created == 'true')
176+ needs : [release-please, publish-main-release]
177+ if : always() && needs.release-please.outputs.release-created == 'true'
296178
297179 steps :
298- - name : Notify about releases
180+ - name : Send notification
299181 uses : actions/github-script@v7
300182 with :
301183 script : |
302- let message = '🚀 **New CodeKeeper Releases**\n\n';
303-
304- if ('${{ needs.release-please.outputs.main-release-created }}' === 'true') {
305- message += `### 🛡️ Main Project: ${{ needs.release-please.outputs.main-tag-name }}\n`;
306- message += '- ✅ Validation scripts updated\n';
307- message += '- ✅ Examples and documentation included\n';
308- message += '- ✅ Release assets available for download\n\n';
309- }
184+ let message = '# 🚀 New Release Published!\n\n';
310185
311- if ('${{ needs.release-please.outputs.eslint-plugin-release-created }}' === 'true') {
312- message += `### 🔌 ESLint Plugin: ${{ needs.release-please.outputs.eslint-plugin-tag-name }}\n`;
313- message += '- ✅ Published to GitHub Packages\n';
314- message += '- ✅ All rules updated with latest validation logic\n';
315- message += '- ✅ Ready for npm installation\n\n';
186+ if ('${{ needs.release-please.outputs.release-created }}' === 'true') {
187+ message += `### 🛡️ CodeKeeper: ${{ needs.release-please.outputs.tag-name }}\n`;
188+ message += '- Validation scripts and guardrails\n';
189+ message += '- Examples and documentation\n';
190+ message += '- Installation script included\n\n';
191+
192+ message += `[View Release](https://github.com/${{ github.repository }}/releases/tag/${{ needs.release-please.outputs.tag-name }})`;
316193 }
317194
318- message += '### 📦 Installation Options\n';
319- message += '1. **Copy-Paste Scripts**: Download release assets\n';
320- message += '2. **ESLint Plugin**: `npm install @thedaviddias/eslint-plugin-codekeeper`\n';
321- message += '3. **Browse Examples**: Check the examples/ directory\n\n';
322- message += 'See the release notes for detailed changes and migration guides.';
195+ console.log(message);
323196
324- // This could be extended to post to Slack, Discord, etc.
325- console. log(message);
197+ // You could send this to Slack, Discord, or other notification services
198+ // For now, just log it to the workflow
0 commit comments