Skip to content
Draft
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
20 changes: 20 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = tab
indent_size = 2

[*.{json,yml,yaml,md}]
indent_style = space
indent_size = 2

[*.md]
trim_trailing_whitespace = false

[package.json]
indent_style = space
indent_size = 2
74 changes: 74 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 2020,
sourceType: 'module',
project: ['./tsconfig.json', './tsconfig.test.json'],
tsconfigRootDir: __dirname,
},
plugins: ['@typescript-eslint', 'import', 'prettier'],
extends: ['eslint:recommended', 'prettier'],
rules: {
// TypeScript specific
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
'no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
'@typescript-eslint/explicit-function-return-type': 'warn',
'@typescript-eslint/explicit-module-boundary-types': 'warn',
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/prefer-nullish-coalescing': 'error',
'@typescript-eslint/prefer-optional-chain': 'error',
'@typescript-eslint/no-non-null-assertion': 'warn',
'@typescript-eslint/no-floating-promises': 'error',
'@typescript-eslint/await-thenable': 'error',
'@typescript-eslint/no-misused-promises': 'error',

// Import organization
'import/order': [
'error',
{
groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
'newlines-between': 'always',
alphabetize: {
order: 'asc',
caseInsensitive: true,
},
},
],
'import/no-duplicates': 'error',
'import/no-unresolved': 'off', // TypeScript handles this

// General code quality
'no-console': 'warn',
'no-debugger': 'error',
'prefer-const': 'error',
'no-var': 'error',
'object-shorthand': 'error',
'prefer-template': 'error',

// Prettier integration
'prettier/prettier': 'error',
},
env: {
node: true,
es2020: true,
},
ignorePatterns: ['dist/', 'node_modules/', '*.js', '*.d.ts'],
overrides: [
{
files: ['tests/**/*.ts', '**/*.test.ts', '**/*.spec.ts'],
env: {
jest: true,
},
globals: {
fail: 'readonly',
},
rules: {
// Relax some rules for test files
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'no-console': 'off',
},
},
],
};
44 changes: 44 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Pull Request

## Description
Brief description of changes made.

## Type of Change
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Documentation update
- [ ] Performance improvement
- [ ] Code refactoring

## Testing
- [ ] Tests pass locally with `yarn test`
- [ ] Linting passes with `yarn lint`
- [ ] Type checking passes with `yarn type-check`
- [ ] Manual testing completed (if applicable)

## API Integration
- [ ] Changes tested with real Agility CMS API
- [ ] No breaking changes to existing API methods
- [ ] New API methods include proper error handling
- [ ] Rate limiting considerations addressed

## Documentation
- [ ] Code is self-documenting with appropriate comments
- [ ] README updated (if applicable)
- [ ] API documentation updated (if applicable)
- [ ] Breaking changes documented

## Checklist
- [ ] My code follows the project's coding standards
- [ ] I have performed a self-review of my own code
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings or errors
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] New and existing unit tests pass locally with my changes

## Related Issues
Closes #(issue number)

## Additional Notes
Any additional information or context about the PR.
168 changes: 168 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
name: CI/CD Pipeline

on:
pull_request:
branches: [main, dev]
push:
branches: [main, dev]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
# Code quality, linting, and unit tests
code-quality-and-unit-tests:
name: Code Quality & Unit Tests
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18, 20, 22]

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'

- name: Install dependencies
run: yarn install --frozen-lockfile

- name: TypeScript type checking
run: yarn type-check

- name: ESLint code quality check
run: yarn lint

- name: Prettier format check
run: yarn format:check

- name: Run unit tests
run: yarn test:unit
env:
AGILITY_PAT: ${{ secrets.AGILITY_PAT }}
AGILITY_GUID: ${{ secrets.AGILITY_GUID }}
AGILITY_WEBSITE: ${{ secrets.AGILITY_WEBSITE }}
AGILITY_LOCALES: ${{ secrets.AGILITY_LOCALES }}
AGILITY_BASE_URL: ${{ secrets.AGILITY_BASE_URL }}

- name: Upload coverage to Codecov
if: matrix.node-version == 20
uses: codecov/codecov-action@v3
with:
file: ./coverage/lcov.info
flags: unittests
name: codecov-umbrella

# Integration tests (run separately for better visibility)
integration-tests:
name: Integration Tests
runs-on: ubuntu-latest
needs: [code-quality-and-unit-tests]
# Run on push to main/dev OR on pull requests (but only if secrets are available)
if: |
(github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev')) ||
(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository)

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js 20
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'yarn'

- name: Install dependencies
run: yarn install --frozen-lockfile

- name: Build project
run: yarn build

- name: Run integration tests
run: yarn test:integration
env:
NODE_ENV: integration
AGILITY_PAT: ${{ secrets.AGILITY_PAT }}
AGILITY_GUID: ${{ secrets.AGILITY_GUID }}
AGILITY_WEBSITE: ${{ secrets.AGILITY_WEBSITE }}
AGILITY_LOCALES: ${{ secrets.AGILITY_LOCALES }}
AGILITY_BASE_URL: ${{ secrets.AGILITY_BASE_URL }}
# Skip if secrets are not available (e.g., on forks)
if: env.AGILITY_PAT != ''

- name: Upload integration test results
uses: actions/upload-artifact@v4
if: always()
with:
name: integration-test-results-${{ github.sha }}
path: coverage/
retention-days: 7

# Security and dependency checks
security-audit:
name: Security Audit
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js 20
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'yarn'

- name: Install dependencies
run: yarn install --frozen-lockfile

- name: Run security audit
run: yarn audit --level moderate

- name: Check for vulnerabilities
run: npx audit-ci --moderate

# Build and package
build-package:
name: Build Package
runs-on: ubuntu-latest
needs: [code-quality-and-unit-tests, security-audit]

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js 20
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'yarn'

- name: Install dependencies
run: yarn install --frozen-lockfile

- name: Clean build
run: yarn clean

- name: Build package
run: yarn build

- name: Check build output
run: |
ls -la dist/
node -e "console.log('Build check:', require('./dist/index.js'))"

- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: build-${{ github.sha }}
path: dist/
retention-days: 7
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
/dist/
/apiCall.ts

# package managers - use yarn only
package-lock.json

# testing
/coverage

Expand All @@ -22,6 +25,7 @@
.env.development.local
.env.test.local
.env.production.local
.env.test

npm-debug.log*
yarn-debug.log*
Expand All @@ -33,4 +37,4 @@ yarn-error.log*
#cussor
.cursor
/.cursor
/rules
/rules
5 changes: 5 additions & 0 deletions .husky/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# Validate commit message format
npx --no -- commitlint --edit "$1"
11 changes: 11 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

# Run lint-staged to check and format staged files
npx lint-staged

# Run TypeScript type checking
echo "🔍 Running TypeScript type checking..."
npx tsc --noEmit

echo "✅ Pre-commit checks passed!"
8 changes: 8 additions & 0 deletions .lintstagedrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
'*.{ts,tsx}': [
'eslint --fix',
'eslint', // Check for remaining errors (will fail on errors but not warnings)
'prettier --write',
],
'*.{json,md,yml,yaml}': ['prettier --write'],
};
8 changes: 8 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
dist/
node_modules/
*.md
*.json
*.yml
*.yaml
package-lock.json
yarn.lock
13 changes: 13 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"semi": true,
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 100,
"tabWidth": 2,
"useTabs": true,
"bracketSpacing": true,
"arrowParens": "avoid",
"endOfLine": "lf",
"quoteProps": "as-needed",
"bracketSameLine": false
}
Loading
Loading