Skip to content

feat: migrate to AWS SDK v3 with complete feature parity (v4.1.2) #8

feat: migrate to AWS SDK v3 with complete feature parity (v4.1.2)

feat: migrate to AWS SDK v3 with complete feature parity (v4.1.2) #8

Workflow file for this run

name: Continuous Integration
on:
push:
branches: [ main, master, feature/*, release/*, hotfix/* ]
pull_request:
branches: [ main, master ]
types: [opened, synchronize, reopened, ready_for_review]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
# Smart change detection and validation
detect-changes:
name: Detect Changes
runs-on: ubuntu-latest
outputs:
has-code-changes: ${{ steps.changes.outputs.code }}
has-dependency-changes: ${{ steps.changes.outputs.dependencies }}
has-workflow-changes: ${{ steps.changes.outputs.workflows }}
should-run-tests: ${{ steps.decision.outputs.run-tests }}
should-publish: ${{ steps.decision.outputs.publish }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Detect file changes
uses: dorny/paths-filter@v3
id: changes
with:
filters: |
code:
- 'index.js'
- 'getAwsOptions.js'
- 'resolveStackOutput.js'
- 'test/**'
dependencies:
- 'package.json'
- 'package-lock.json'
workflows:
- '.github/workflows/**'
- name: Make decisions
id: decision
run: |
# Always run tests for PR or if code/deps changed
if [[ "${{ github.event_name }}" == "pull_request" ]] || \
[[ "${{ steps.changes.outputs.code }}" == "true" ]] || \
[[ "${{ steps.changes.outputs.dependencies }}" == "true" ]]; then
echo "run-tests=true" >> $GITHUB_OUTPUT
else
echo "run-tests=false" >> $GITHUB_OUTPUT
fi
# Only publish on main/master push with code changes
if [[ "${{ github.event_name }}" == "push" ]] && \
[[ "${{ github.ref }}" == "refs/heads/main" || "${{ github.ref }}" == "refs/heads/master" ]] && \
[[ "${{ steps.changes.outputs.code }}" == "true" ]]; then
echo "publish=true" >> $GITHUB_OUTPUT
else
echo "publish=false" >> $GITHUB_OUTPUT
fi
# Comprehensive testing matrix
test:
name: Test (Node.js ${{ matrix.node-version }})
runs-on: ubuntu-latest
needs: detect-changes
if: needs.detect-changes.outputs.should-run-tests == 'true'
strategy:
fail-fast: false
matrix:
node-version: [18.x, 20.x]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run linting
run: |
if npm run lint --if-present; then
echo "Linting passed"
else
echo "No linting script found, skipping"
fi
- name: Run type checking
run: |
if npm run type-check --if-present; then
echo "Type checking passed"
else
echo "No type checking script found, skipping"
fi
- name: Run tests with coverage
run: npm run test:coverage
- name: Upload coverage to Codecov
if: matrix.node-version == '18.x'
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: false
- name: Run basic integration test
run: npm run test:basic
# Security and quality checks
security:
name: Security & Quality
runs-on: ubuntu-latest
needs: detect-changes
if: needs.detect-changes.outputs.should-run-tests == 'true'
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18.x'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Security audit
run: |
echo "Running security audit..."
npm audit --audit-level high
- name: Check for outdated dependencies
run: |
echo "Checking for outdated dependencies..."
npm outdated || echo "Some dependencies may be outdated"
- name: License check
run: |
echo "Validating license compliance..."
if command -v license-checker &> /dev/null; then
npx license-checker --summary
else
echo "License checker not available, skipping"
fi
# Build validation
build:
name: Build Validation
runs-on: ubuntu-latest
needs: detect-changes
if: needs.detect-changes.outputs.should-run-tests == 'true'
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18.x'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Validate package.json
run: |
echo "Validating package.json structure..."
node -e "
const pkg = require('./package.json');
const required = ['name', 'version', 'description', 'main', 'author', 'license'];
const missing = required.filter(field => !pkg[field]);
if (missing.length > 0) {
console.error('Missing required fields:', missing.join(', '));
process.exit(1);
}
console.log('Package.json validation passed');
"
- name: Test package installation
run: |
echo "Testing package installation..."
npm pack
PKG_FILE=$(ls *.tgz)
npm install -g "$PKG_FILE"
echo "Package installs successfully"
# Pre-publish validation
pre-publish:
name: Pre-publish Validation
runs-on: ubuntu-latest
needs: [test, security, build]
if: needs.detect-changes.outputs.should-publish == 'true'
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18.x'
registry-url: 'https://registry.npmjs.org'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Final test run
run: npm test
- name: Check if version exists on NPM
run: |
CURRENT_VERSION=$(node -p "require('./package.json').version")
echo "Current version: $CURRENT_VERSION"
if npm view @flaconi/serverless-s3-sync@$CURRENT_VERSION version &>/dev/null; then
echo "Version $CURRENT_VERSION already exists on NPM"
echo "Please bump the version before publishing"
exit 1
else
echo "Version $CURRENT_VERSION is available for publishing"
fi
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Dry run publish
run: npm publish --dry-run --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Publish to NPM
run: |
echo "Publishing to NPM..."
npm publish --access public
echo "Successfully published to NPM"
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
# Status reporting
ci-success:
name: CI Success
runs-on: ubuntu-latest
needs: [detect-changes, test, security, build]
if: always() && (needs.detect-changes.outputs.should-run-tests == 'false' || (needs.test.result == 'success' && needs.security.result == 'success' && needs.build.result == 'success'))
steps:
- name: Report success
run: |
echo "All CI checks passed successfully!"
echo "Changes detected: ${{ needs.detect-changes.outputs.has-code-changes }}"
echo "Tests required: ${{ needs.detect-changes.outputs.should-run-tests }}"
echo "Publish ready: ${{ needs.detect-changes.outputs.should-publish }}"