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
82 changes: 82 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Dependencies
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Build output
dist/
build/

# Git
.git/
.gitignore

# Environment files
.env
.env.*
!.env.example

# IDE and editor files
.vscode/
.idea/
*.swp
*.swo

# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# Logs
logs/
*.log

# Runtime data
pids/
*.pid
*.seed
*.pid.lock

# Coverage directory
coverage/
*.lcov

# Temporary folders
tmp/
temp/

# Documentation
docs/
ai_context/
README.md
CONTRIBUTING.md
CODE_OF_CONDUCT.md
LICENSE
SECURITY.md

# Package manager files
package-lock.json
.yarn-integrity
.yarn/

# TypeScript
*.tsbuildinfo

# Cache
.cache/
.parcel-cache/
.eslintcache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Testing
test/
tests/
__tests__/
6 changes: 4 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
NODE_ENV=development
PORT=3000
TARGET_PLATFORM=telegram
# For local development use: redis://localhost:6379
# For Docker Compose, this gets overridden automatically to: redis://redis:6379
REDIS_URL=redis://localhost:6379
UNTHREAD_WEBHOOK_SECRET=your_signing_secret_here
TARGET_PLATFORM=telegram
UNTHREAD_WEBHOOK_SECRET=your_webhook_secret_here
74 changes: 74 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: Build

on:
push:
branches: [dev]

env:
REGISTRY_DOCKERHUB: wgtechlabs/unthread-webhook-server
REGISTRY_GHCR: ghcr.io/wgtechlabs/unthread-webhook-server

jobs:
build-dev:
name: Build Development Images
runs-on: ubuntu-latest

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

- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata
id: meta
run: |
echo "short_sha=${GITHUB_SHA::7}" >> $GITHUB_OUTPUT
echo "build_date=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT

- name: Build and push development images
uses: docker/build-push-action@v5
with:
context: .
push: true
platforms: linux/amd64
tags: |
${{ env.REGISTRY_DOCKERHUB }}:dev
${{ env.REGISTRY_DOCKERHUB }}:dev-${{ steps.meta.outputs.short_sha }}
${{ env.REGISTRY_GHCR }}:dev
${{ env.REGISTRY_GHCR }}:dev-${{ steps.meta.outputs.short_sha }}
labels: |
org.opencontainers.image.title=Unthread Webhook Server
org.opencontainers.image.description=Development build of Unthread Webhook Server
org.opencontainers.image.version=dev-${{ steps.meta.outputs.short_sha }}
org.opencontainers.image.created=${{ steps.meta.outputs.build_date }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Development build summary
run: |
echo "## 🔨 Development Build Complete" >> $GITHUB_STEP_SUMMARY
echo "**Images built and pushed:**" >> $GITHUB_STEP_SUMMARY
echo "- \`${{ env.REGISTRY_DOCKERHUB }}:dev\`" >> $GITHUB_STEP_SUMMARY
echo "- \`${{ env.REGISTRY_DOCKERHUB }}:dev-${{ steps.meta.outputs.short_sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "- \`${{ env.REGISTRY_GHCR }}:dev\`" >> $GITHUB_STEP_SUMMARY
echo "- \`${{ env.REGISTRY_GHCR }}:dev-${{ steps.meta.outputs.short_sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**Test the dev image:**" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
echo "docker pull ${{ env.REGISTRY_DOCKERHUB }}:dev" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
135 changes: 135 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
name: Release

on:
release:
types: [published]

env:
REGISTRY_DOCKERHUB: wgtechlabs/unthread-webhook-server
REGISTRY_GHCR: ghcr.io/wgtechlabs/unthread-webhook-server

jobs:
build-production:
name: Build Production Images
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')

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

- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver: cloud
endpoint: "wgtechlabs/unthread-bot-builder"
install: true

- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract version from package.json
id: version
run: |
VERSION=$(node -p "require('./package.json').version")
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "major=$(echo $VERSION | cut -d. -f1)" >> $GITHUB_OUTPUT
echo "minor=$(echo $VERSION | cut -d. -f1-2)" >> $GITHUB_OUTPUT
echo "patch=$(echo $VERSION | cut -d. -f1-3)" >> $GITHUB_OUTPUT
echo "build_date=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT

- name: Generate Docker tags
id: tags
run: |
VERSION="${{ steps.version.outputs.version }}"
MAJOR="${{ steps.version.outputs.major }}"
MINOR="${{ steps.version.outputs.minor }}"
PATCH="${{ steps.version.outputs.patch }}"

# Docker Hub tags (no 'v' prefix)
DOCKERHUB_TAGS="${{ env.REGISTRY_DOCKERHUB }}:latest"
DOCKERHUB_TAGS="$DOCKERHUB_TAGS,${{ env.REGISTRY_DOCKERHUB }}:$VERSION"
DOCKERHUB_TAGS="$DOCKERHUB_TAGS,${{ env.REGISTRY_DOCKERHUB }}:$PATCH"
DOCKERHUB_TAGS="$DOCKERHUB_TAGS,${{ env.REGISTRY_DOCKERHUB }}:$MINOR"
DOCKERHUB_TAGS="$DOCKERHUB_TAGS,${{ env.REGISTRY_DOCKERHUB }}:$MAJOR"

# GitHub Container Registry tags (with 'v' prefix)
GHCR_TAGS="${{ env.REGISTRY_GHCR }}:latest"
GHCR_TAGS="$GHCR_TAGS,${{ env.REGISTRY_GHCR }}:v$VERSION"
GHCR_TAGS="$GHCR_TAGS,${{ env.REGISTRY_GHCR }}:v$PATCH"
GHCR_TAGS="$GHCR_TAGS,${{ env.REGISTRY_GHCR }}:v$MINOR"
GHCR_TAGS="$GHCR_TAGS,${{ env.REGISTRY_GHCR }}:v$MAJOR"

# Combine all tags
ALL_TAGS="$DOCKERHUB_TAGS,$GHCR_TAGS"

echo "tags=$ALL_TAGS" >> $GITHUB_OUTPUT

- name: Build and push production images
uses: docker/build-push-action@v5
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
tags: ${{ steps.tags.outputs.tags }}
labels: |
org.opencontainers.image.title=Unthread Webhook Server
org.opencontainers.image.description=A Node.js server application that receives webhook events from Unthread.io
org.opencontainers.image.version=${{ steps.version.outputs.version }}
org.opencontainers.image.created=${{ steps.version.outputs.build_date }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
org.opencontainers.image.url=${{ github.server_url }}/${{ github.repository }}
org.opencontainers.image.licenses=GPL-3.0
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Run Trivy vulnerability scanner
uses: aquasecurity/[email protected]
with:
image-ref: ${{ env.REGISTRY_DOCKERHUB }}:${{ steps.version.outputs.version }}
format: 'sarif'
output: 'trivy-results.sarif'

- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: 'trivy-results.sarif'

- name: Production release summary
run: |
echo "## 🚀 Production Release Complete" >> $GITHUB_STEP_SUMMARY
echo "**Version:** \`${{ steps.version.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY
echo "**Release:** \`${{ github.event.release.tag_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Docker Hub Images:**" >> $GITHUB_STEP_SUMMARY
echo "- \`${{ env.REGISTRY_DOCKERHUB }}:latest\`" >> $GITHUB_STEP_SUMMARY
echo "- \`${{ env.REGISTRY_DOCKERHUB }}:${{ steps.version.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY
echo "- \`${{ env.REGISTRY_DOCKERHUB }}:${{ steps.version.outputs.patch }}\`" >> $GITHUB_STEP_SUMMARY
echo "- \`${{ env.REGISTRY_DOCKERHUB }}:${{ steps.version.outputs.minor }}\`" >> $GITHUB_STEP_SUMMARY
echo "- \`${{ env.REGISTRY_DOCKERHUB }}:${{ steps.version.outputs.major }}\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**GitHub Container Registry Images:**" >> $GITHUB_STEP_SUMMARY
echo "- \`${{ env.REGISTRY_GHCR }}:latest\`" >> $GITHUB_STEP_SUMMARY
echo "- \`${{ env.REGISTRY_GHCR }}:v${{ steps.version.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY
echo "- \`${{ env.REGISTRY_GHCR }}:v${{ steps.version.outputs.patch }}\`" >> $GITHUB_STEP_SUMMARY
echo "- \`${{ env.REGISTRY_GHCR }}:v${{ steps.version.outputs.minor }}\`" >> $GITHUB_STEP_SUMMARY
echo "- \`${{ env.REGISTRY_GHCR }}:v${{ steps.version.outputs.major }}\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Deploy with:**" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
echo "docker pull ${{ env.REGISTRY_DOCKERHUB }}:latest" >> $GITHUB_STEP_SUMMARY
echo "# OR" >> $GITHUB_STEP_SUMMARY
echo "docker pull ${{ env.REGISTRY_GHCR }}:latest" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
37 changes: 37 additions & 0 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Validate

on:
pull_request:
branches: [dev, main]

jobs:
validate:
name: Validate Changes
runs-on: ubuntu-latest

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

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

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

- name: Type checking
run: yarn type-check

- name: Build TypeScript
run: yarn build

- name: Test Docker build (no push)
run: |
echo "Testing Docker build..."
docker build -t test-build .
echo "Build successful, cleaning up..."
docker image rm test-build
echo "✅ Docker build test completed"
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,9 @@ ai_context/

# Enforce Yarn usage - ignore npm lockfile
package-lock.json

# Environment files with sensitive data
.env
.env.local
.env.*.local
.env.production
Loading