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
54 changes: 54 additions & 0 deletions .github/workflows/github-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: GitHub Release

on:
push:
tags:
- 'v*'

permissions:
contents: write

jobs:
release:
name: πŸš€ Create GitHub Release
runs-on: ubuntu-latest

steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
fetch-depth: 0

- name: 🏷️ Create GitHub Release
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
with:
script: |
const tag = context.ref.replace('refs/tags/', '');
const version = tag.replace(/^v/, '');

const installBlock = [
'## Install',
'```sh',
`npm install @mcabreradev/filter@${version}`,
`pnpm add @mcabreradev/filter@${version}`,
`yarn add @mcabreradev/filter@${version}`,
'```',
'',
`πŸ“¦ [View on npm](https://www.npmjs.com/package/@mcabreradev/filter/v/${version})`,
'',
'---',
'',
].join('\n');

const { data: release } = await github.rest.repos.createRelease({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: tag,
name: `Release ${tag}`,
body: installBlock,
generate_release_notes: true,
draft: false,
prerelease: false,
});

console.log(`βœ… Release created: ${release.html_url}`);
42 changes: 28 additions & 14 deletions .github/workflows/npm-publish-manual.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,24 @@ jobs:
echo "Build files:"
ls -la build/

- name: πŸ”’ Security audit
run: pnpm audit --audit-level=high

- name: πŸ” Running Check/Test Suite
run: pnpm run check

- name: πŸ” Determine version bump from PR title or labels
id: version
env:
PR_TITLE: ${{ github.event.pull_request.title }}
PR_LABELS: ${{ toJSON(github.event.pull_request.labels) }}
run: |
VERSION_TYPE=""
DETECTION_METHOD=""

# ============================================
# PASO 1: Intentar detectar por tΓ­tulo del PR
# ============================================
PR_TITLE="${{ github.event.pull_request.title }}"
echo "πŸ“‹ PR Title: $PR_TITLE"

# Extraer el tipo (soporta: "type: msg", "type(scope): msg", "type!: msg")
Expand Down Expand Up @@ -100,8 +105,7 @@ jobs:
if [ -z "$VERSION_TYPE" ]; then
echo "⚠️ No valid conventional commit format in title, checking labels..."

LABELS='${{ toJSON(github.event.pull_request.labels) }}'
LABEL_NAMES=$(echo "$LABELS" | jq -r '.[].name' 2>/dev/null || echo "")
LABEL_NAMES=$(echo "$PR_LABELS" | jq -r '.[].name' 2>/dev/null || echo "")

if [ -n "$LABEL_NAMES" ]; then
echo "🏷️ Labels found: $LABEL_NAMES"
Expand Down Expand Up @@ -144,26 +148,36 @@ jobs:

echo "type=$VERSION_TYPE" >> $GITHUB_OUTPUT

- name: πŸ“ˆ Bump version
- name: πŸ“ˆ Bump version (local only)
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
pnpm version ${{ steps.version.outputs.type }} --no-git-tag-version

- name: πŸ”Ž Check version doesn't already exist on npm
run: |
NEW_VERSION=$(node -p "require('./package.json').version")
echo "NEW_VERSION=$NEW_VERSION" >> $GITHUB_ENV
if npm view "@mcabreradev/filter@$NEW_VERSION" version 2>/dev/null | grep -q "$NEW_VERSION"; then
echo "❌ Version $NEW_VERSION already exists on npm. Aborting to avoid duplicate publish."
exit 1
fi
echo "βœ… Version $NEW_VERSION is available for publishing."

- name: πŸš€ Publish to npm
run: pnpm publish --no-git-checks --access public --provenance
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: πŸ“ Commit version bump
run: |
git add package.json
git commit -m "chore: bump version to $NEW_VERSION [skip ci]"

- name: πŸ”„ Push version bump
run: |
git push origin main
run: git push origin main

- name: πŸ“ Create Git Tag
- name: 🏷️ Create Git Tag
run: |
git tag -a "v${{ env.NEW_VERSION }}" -m "Release v${{ env.NEW_VERSION }}"
git push origin "v${{ env.NEW_VERSION }}"

- name: πŸš€ Publish to npm
run: pnpm publish --no-git-checks --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
git tag -a "v$NEW_VERSION" -m "Release v$NEW_VERSION"
git push origin "v$NEW_VERSION"
54 changes: 54 additions & 0 deletions .github/workflows/pr-title-lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: PR Title Lint

on:
pull_request:
types: [opened, edited, synchronize, reopened]
branches:
- main

permissions:
pull-requests: read

jobs:
lint-pr-title:
name: πŸ“‹ Validate PR Title
runs-on: ubuntu-latest

steps:
- name: βœ… Validate conventional commit format
env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: |
PATTERN='^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert|major|breaking|minor|feature|bugfix|hotfix|patch)(\([^)]+\))?!?:[[:space:]].+'

echo "πŸ“‹ PR Title: $PR_TITLE"
echo ""

if echo "$PR_TITLE" | grep -qE "$PATTERN"; then
echo "βœ… PR title follows conventional commits format."
else
echo "❌ PR title does not follow conventional commits format."
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo " Expected format:"
echo ""
echo " <type>(<scope>): <description>"
echo " <type>!: <description> (breaking change)"
echo " <type>(<scope>)!: <description> (breaking change)"
echo ""
echo " Valid types:"
echo " MINOR bump β†’ feat, feature, minor"
echo " PATCH bump β†’ fix, bugfix, hotfix, chore, docs,"
echo " style, refactor, perf, test, build,"
echo " ci, revert"
echo " MAJOR bump β†’ major, breaking, or any type with !"
echo ""
echo " Examples:"
echo " feat: add \$in operator support"
echo " fix(core): resolve cache invalidation bug"
echo " feat!: remove deprecated find() API"
echo " chore(deps): update dependencies"
echo " refactor(predicate): simplify factory pattern"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
exit 1
fi
101 changes: 101 additions & 0 deletions .github/workflows/security-audit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
name: Security Audit

on:
schedule:
- cron: '0 8 * * 1' # every Monday at 08:00 UTC
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch:

permissions:
contents: read
issues: write

jobs:
audit:
name: πŸ”’ Security Audit
runs-on: ubuntu-latest

steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5

- name: πŸ“¦ Setup pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4
with:
version: 10

- name: βŽ” Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
with:
node-version: 20
cache: 'pnpm'

- name: πŸ“₯ Install dependencies
run: pnpm install --frozen-lockfile --ignore-scripts

- name: πŸ” Audit (high & critical)
id: audit_high
run: pnpm audit --audit-level=high
continue-on-error: true

- name: πŸ“‹ Audit report (all severities)
id: audit_full
run: |
echo "## Security Audit Report" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
pnpm audit --json 2>/dev/null | node -e "
const chunks = [];
process.stdin.on('data', c => chunks.push(c));
process.stdin.on('end', () => {
try {
const data = JSON.parse(chunks.join(''));
const meta = data.metadata || {};
const vulns = meta.vulnerabilities || {};
const total = (vulns.critical||0) + (vulns.high||0) + (vulns.moderate||0) + (vulns.low||0) + (vulns.info||0);
console.log('| Severity | Count |');
console.log('|---|---|');
if (vulns.critical) console.log('| πŸ”΄ Critical | ' + vulns.critical + ' |');
if (vulns.high) console.log('| πŸ”΄ High | ' + vulns.high + ' |');
if (vulns.moderate) console.log('| 🟑 Moderate | ' + vulns.moderate + ' |');
if (vulns.low) console.log('| 🟒 Low | ' + vulns.low + ' |');
if (total === 0) console.log('| βœ… None | 0 |');
} catch(e) {
console.log('Could not parse audit output.');
}
});
" >> $GITHUB_STEP_SUMMARY
continue-on-error: true

- name: 🚨 Open issue if high/critical vulnerabilities found (scheduled only)
if: steps.audit_high.outcome == 'failure' && github.event_name == 'schedule'
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
with:
script: |
const title = 'πŸ”’ Security vulnerabilities found in dependencies';
const { data: issues } = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
labels: 'security',
});
const existing = issues.find(i => i.title === title);
if (!existing) {
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title,
body: `The weekly security audit found high or critical vulnerabilities in dependencies.\n\nRun \`pnpm audit\` locally to see details and \`pnpm audit --fix\` or update \`pnpm.overrides\` to resolve them.\n\nWorkflow run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}`,
labels: ['security'],
});
}

- name: ❌ Fail if high/critical vulnerabilities found
if: steps.audit_high.outcome == 'failure'
run: |
echo "High or critical vulnerabilities were found. See audit report above."
exit 1
5 changes: 5 additions & 0 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ name: Code Check
on:
push:
branches:
- main
- dev
- stage
- master
- prod
pull_request:
branches:
- main
- dev
- stage
- master
Expand Down Expand Up @@ -60,6 +62,9 @@ jobs:
- name: πŸ“Š Generate coverage report
run: pnpm run test:coverage

- name: πŸ—οΈ Build
run: pnpm run build

- name: Re Check All
run: pnpm run check

Expand Down
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@mcabreradev/filter",
"version": "5.9.0",
"version": "5.8.3",
"type": "module",
"description": "A powerful, SQL-like array filtering library for TypeScript and JavaScript with advanced pattern matching, MongoDB-style operators, deep object comparison, and zero dependencies",
"scripts": {
Expand Down Expand Up @@ -297,8 +297,7 @@
],
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org",
"provenance": true
"registry": "https://registry.npmjs.org"
},
"pnpm": {
"overrides": {
Expand Down
Loading