publish.yml•7.84 kB
name: Publish to NPM
on:
release:
types: [published]
jobs:
test:
name: Test and Build
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [16.x, 18.x, 20.x]
steps:
- name: Checkout code
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 type checking
run: npm run typecheck
- name: Build project
run: npm run build
- name: Test executable permissions (Unix)
if: runner.os != 'Windows'
run: |
test -x dist/index.js || chmod +x dist/index.js
test -x dist/index.js
shell: bash
- name: Test package execution
run: |
# Test that the server validates environment variables properly
# Use different timeout methods for different OS
if command -v timeout >/dev/null 2>&1; then
# Linux/Windows with timeout command
output=$(timeout 5s node dist/index.js 2>&1 || true)
elif command -v gtimeout >/dev/null 2>&1; then
# macOS with coreutils installed
output=$(gtimeout 5s node dist/index.js 2>&1 || true)
else
# Fallback: run with background process and kill after 5 seconds
node dist/index.js > temp_output.txt 2>&1 &
PID=$!
sleep 5
kill $PID 2>/dev/null || true
wait $PID 2>/dev/null || true
output=$(cat temp_output.txt || echo "")
rm -f temp_output.txt
fi
echo "Server output: $output"
# Check that it properly validates required environment variables
if echo "$output" | grep -q "TEMPO_BASE_URL.*required"; then
echo "✅ Server properly validates environment variables"
exit 0
else
echo "❌ Server validation test failed"
echo "Expected server to require TEMPO_BASE_URL environment variable"
exit 1
fi
shell: bash
security:
name: Security Audit
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run security audit
run: npm audit --audit-level=high
publish:
name: Publish to NPM
needs: [test, security]
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # Required for provenance
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
registry-url: 'https://registry.npmjs.org'
- name: Install dependencies
run: npm ci
- name: Build project
run: npm run build
- name: Set executable permissions
run: chmod +x dist/index.js
- name: Verify package.json version matches release tag
run: |
PACKAGE_VERSION=$(node -p "require('./package.json').version")
RELEASE_TAG=${GITHUB_REF#refs/tags/}
if [ "v$PACKAGE_VERSION" != "$RELEASE_TAG" ]; then
echo "Version mismatch: package.json has v$PACKAGE_VERSION, release tag is $RELEASE_TAG"
exit 1
fi
echo "Version verified: $RELEASE_TAG"
shell: bash
- name: Test package locally
run: |
npm pack
PACKAGE_FILE=$(ls *.tgz)
echo "Package created: $PACKAGE_FILE"
# Test that we can install and run the package
npm install -g "$PACKAGE_FILE"
# Verify the binary is accessible and validates environment
which tempo-filler-mcp-server || echo "Binary not found in PATH"
# Test that the installed binary validates environment properly
if command -v timeout >/dev/null 2>&1; then
output=$(timeout 5s tempo-filler-mcp-server 2>&1 || true)
elif command -v gtimeout >/dev/null 2>&1; then
output=$(gtimeout 5s tempo-filler-mcp-server 2>&1 || true)
else
tempo-filler-mcp-server > temp_output.txt 2>&1 &
PID=$!
sleep 5
kill $PID 2>/dev/null || true
wait $PID 2>/dev/null || true
output=$(cat temp_output.txt || echo "")
rm -f temp_output.txt
fi
if echo "$output" | grep -q "TEMPO_BASE_URL.*required"; then
echo "✅ Installed binary properly validates environment variables"
else
echo "⚠️ Binary validation test inconclusive (may be normal)"
fi
shell: bash
- name: Publish to NPM
run: npm publish --provenance
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Verify publication
run: |
# Wait a moment for NPM registry to update
sleep 10
# Try to install the published package
npm install -g @tranzact/tempo-filler-mcp-server@latest
# Verify it's accessible via npx and validates environment
if command -v timeout >/dev/null 2>&1; then
output=$(timeout 10s npx --yes @tranzact/tempo-filler-mcp-server 2>&1 || true)
elif command -v gtimeout >/dev/null 2>&1; then
output=$(gtimeout 10s npx --yes @tranzact/tempo-filler-mcp-server 2>&1 || true)
else
npx --yes @tranzact/tempo-filler-mcp-server > temp_output.txt 2>&1 &
PID=$!
sleep 10
kill $PID 2>/dev/null || true
wait $PID 2>/dev/null || true
output=$(cat temp_output.txt || echo "")
rm -f temp_output.txt
fi
if echo "$output" | grep -q "TEMPO_BASE_URL.*required"; then
echo "✅ Published package works correctly via npx"
else
echo "⚠️ NPX test inconclusive but package was installed successfully"
fi
shell: bash
post-publish:
name: Post-publish validation
needs: [publish]
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- name: Test npx execution across platforms
run: |
# Test that npx can execute the package and validates environment
if command -v timeout >/dev/null 2>&1; then
output=$(timeout 30s npx --yes @tranzact/tempo-filler-mcp-server 2>&1 || true)
elif command -v gtimeout >/dev/null 2>&1; then
output=$(gtimeout 30s npx --yes @tranzact/tempo-filler-mcp-server 2>&1 || true)
else
npx --yes @tranzact/tempo-filler-mcp-server > temp_output.txt 2>&1 &
PID=$!
sleep 30
kill $PID 2>/dev/null || true
wait $PID 2>/dev/null || true
output=$(cat temp_output.txt || echo "")
rm -f temp_output.txt
fi
if echo "$output" | grep -q "TEMPO_BASE_URL.*required"; then
echo "✅ NPX execution successful on ${{ matrix.os }}"
else
echo "⚠️ NPX test completed on ${{ matrix.os }} (output may vary)"
fi
shell: bash