mirror of
https://github.com/stackblitz-labs/bolt.diy
synced 2025-06-26 18:26:38 +00:00
Update workflows
This commit is contained in:
parent
3178504069
commit
120730c860
39
.github/actions/setup-and-build/action.yaml
vendored
39
.github/actions/setup-and-build/action.yaml
vendored
@ -1,39 +0,0 @@
|
||||
name: Setup and Build
|
||||
description: Generic setup action
|
||||
inputs:
|
||||
pnpm-version:
|
||||
required: false
|
||||
type: string
|
||||
default: '9.4.0'
|
||||
node-version:
|
||||
required: false
|
||||
type: string
|
||||
default: '20.15.1'
|
||||
sentry-auth-token:
|
||||
required: false
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
|
||||
steps:
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: ${{ inputs.pnpm-version }}
|
||||
run_install: false
|
||||
|
||||
- name: Set Node.js version to ${{ inputs.node-version }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ inputs.node-version }}
|
||||
cache: pnpm
|
||||
|
||||
- name: Install dependencies and build project
|
||||
shell: bash
|
||||
run: |
|
||||
pnpm install
|
||||
pnpm run build
|
||||
env:
|
||||
SENTRY_AUTH_TOKEN: ${{ inputs.sentry-auth-token }}
|
||||
261
.github/scripts/generate-changelog.sh
vendored
261
.github/scripts/generate-changelog.sh
vendored
@ -1,261 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Ensure we're running in bash
|
||||
if [ -z "$BASH_VERSION" ]; then
|
||||
echo "This script requires bash. Please run with: bash $0" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Ensure we're using bash 4.0 or later for associative arrays
|
||||
if ((BASH_VERSINFO[0] < 4)); then
|
||||
echo "This script requires bash version 4 or later" >&2
|
||||
echo "Current bash version: $BASH_VERSION" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set default values for required environment variables if not in GitHub Actions
|
||||
if [ -z "$GITHUB_ACTIONS" ]; then
|
||||
: "${GITHUB_SERVER_URL:=https://github.com}"
|
||||
: "${GITHUB_REPOSITORY:=stackblitz-labs/bolt.diy}"
|
||||
: "${GITHUB_OUTPUT:=/tmp/github_output}"
|
||||
touch "$GITHUB_OUTPUT"
|
||||
|
||||
# Running locally
|
||||
echo "Running locally - checking for upstream remote..."
|
||||
MAIN_REMOTE="origin"
|
||||
if git remote -v | grep -q "upstream"; then
|
||||
MAIN_REMOTE="upstream"
|
||||
fi
|
||||
MAIN_BRANCH="main" # or "master" depending on your repository
|
||||
|
||||
# Ensure we have latest tags
|
||||
git fetch ${MAIN_REMOTE} --tags
|
||||
|
||||
# Use the remote reference for git log
|
||||
GITLOG_REF="${MAIN_REMOTE}/${MAIN_BRANCH}"
|
||||
else
|
||||
# Running in GitHub Actions
|
||||
GITLOG_REF="HEAD"
|
||||
fi
|
||||
|
||||
# Get the latest tag
|
||||
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
|
||||
|
||||
# Start changelog file
|
||||
echo "# 🚀 Release v${NEW_VERSION}" > changelog.md
|
||||
echo "" >> changelog.md
|
||||
echo "## What's Changed 🌟" >> changelog.md
|
||||
echo "" >> changelog.md
|
||||
|
||||
if [ -z "$LATEST_TAG" ]; then
|
||||
echo "### 🎉 First Release" >> changelog.md
|
||||
echo "" >> changelog.md
|
||||
echo "Exciting times! This marks our first release. Thanks to everyone who contributed! 🙌" >> changelog.md
|
||||
echo "" >> changelog.md
|
||||
COMPARE_BASE="$(git rev-list --max-parents=0 HEAD)"
|
||||
else
|
||||
echo "### 🔄 Changes since $LATEST_TAG" >> changelog.md
|
||||
echo "" >> changelog.md
|
||||
COMPARE_BASE="$LATEST_TAG"
|
||||
fi
|
||||
|
||||
# Function to extract conventional commit type and associated emoji
|
||||
get_commit_type() {
|
||||
local msg="$1"
|
||||
if [[ $msg =~ ^feat(\(.+\))?:|^feature(\(.+\))?: ]]; then echo "✨ Features"
|
||||
elif [[ $msg =~ ^fix(\(.+\))?: ]]; then echo "🐛 Bug Fixes"
|
||||
elif [[ $msg =~ ^docs(\(.+\))?: ]]; then echo "📚 Documentation"
|
||||
elif [[ $msg =~ ^style(\(.+\))?: ]]; then echo "💎 Styles"
|
||||
elif [[ $msg =~ ^refactor(\(.+\))?: ]]; then echo "♻️ Code Refactoring"
|
||||
elif [[ $msg =~ ^perf(\(.+\))?: ]]; then echo "⚡ Performance Improvements"
|
||||
elif [[ $msg =~ ^test(\(.+\))?: ]]; then echo "🧪 Tests"
|
||||
elif [[ $msg =~ ^build(\(.+\))?: ]]; then echo "🛠️ Build System"
|
||||
elif [[ $msg =~ ^ci(\(.+\))?: ]]; then echo "⚙️ CI"
|
||||
elif [[ $msg =~ ^chore(\(.+\))?: ]]; then echo "" # Skip chore commits
|
||||
else echo "🔍 Other Changes" # Default category with emoji
|
||||
fi
|
||||
}
|
||||
|
||||
# Initialize associative arrays
|
||||
declare -A CATEGORIES
|
||||
declare -A COMMITS_BY_CATEGORY
|
||||
declare -A ALL_AUTHORS
|
||||
declare -A NEW_CONTRIBUTORS
|
||||
|
||||
# Get all historical authors before the compare base
|
||||
while IFS= read -r author; do
|
||||
ALL_AUTHORS["$author"]=1
|
||||
done < <(git log "${COMPARE_BASE}" --pretty=format:"%ae" | sort -u)
|
||||
|
||||
# Process all commits since last tag
|
||||
while IFS= read -r commit_line; do
|
||||
if [[ ! $commit_line =~ ^[a-f0-9]+\| ]]; then
|
||||
echo "WARNING: Skipping invalid commit line format: $commit_line" >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
HASH=$(echo "$commit_line" | cut -d'|' -f1)
|
||||
COMMIT_MSG=$(echo "$commit_line" | cut -d'|' -f2)
|
||||
BODY=$(echo "$commit_line" | cut -d'|' -f3)
|
||||
# Skip if hash doesn't match the expected format
|
||||
if [[ ! $HASH =~ ^[a-f0-9]{40}$ ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
HASH=$(echo "$commit_line" | cut -d'|' -f1)
|
||||
COMMIT_MSG=$(echo "$commit_line" | cut -d'|' -f2)
|
||||
BODY=$(echo "$commit_line" | cut -d'|' -f3)
|
||||
|
||||
|
||||
# Validate hash format
|
||||
if [[ ! $HASH =~ ^[a-f0-9]{40}$ ]]; then
|
||||
echo "WARNING: Invalid commit hash format: $HASH" >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
# Check if it's a merge commit
|
||||
if [[ $COMMIT_MSG =~ Merge\ pull\ request\ #([0-9]+) ]]; then
|
||||
# echo "Processing as merge commit" >&2
|
||||
PR_NUM="${BASH_REMATCH[1]}"
|
||||
|
||||
# Extract the PR title from the merge commit body
|
||||
PR_TITLE=$(echo "$BODY" | grep -v "^Merge pull request" | head -n 1)
|
||||
|
||||
# Only process if it follows conventional commit format
|
||||
CATEGORY=$(get_commit_type "$PR_TITLE")
|
||||
|
||||
if [ -n "$CATEGORY" ]; then # Only process if it's a conventional commit
|
||||
# Get PR author's GitHub username
|
||||
GITHUB_USERNAME=$(gh pr view "$PR_NUM" --json author --jq '.author.login')
|
||||
|
||||
if [ -n "$GITHUB_USERNAME" ]; then
|
||||
# Check if this is a first-time contributor
|
||||
AUTHOR_EMAIL=$(git show -s --format='%ae' "$HASH")
|
||||
if [ -z "${ALL_AUTHORS[$AUTHOR_EMAIL]}" ]; then
|
||||
NEW_CONTRIBUTORS["$GITHUB_USERNAME"]=1
|
||||
ALL_AUTHORS["$AUTHOR_EMAIL"]=1
|
||||
fi
|
||||
|
||||
CATEGORIES["$CATEGORY"]=1
|
||||
COMMITS_BY_CATEGORY["$CATEGORY"]+="* ${PR_TITLE#*: } ([#$PR_NUM](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/pull/$PR_NUM)) by @$GITHUB_USERNAME"$'\n'
|
||||
else
|
||||
COMMITS_BY_CATEGORY["$CATEGORY"]+="* ${PR_TITLE#*: } ([#$PR_NUM](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/pull/$PR_NUM))"$'\n'
|
||||
fi
|
||||
fi
|
||||
# Check if it's a squash merge by looking for (#NUMBER) pattern
|
||||
elif [[ $COMMIT_MSG =~ \(#([0-9]+)\) ]]; then
|
||||
# echo "Processing as squash commit" >&2
|
||||
PR_NUM="${BASH_REMATCH[1]}"
|
||||
|
||||
# Only process if it follows conventional commit format
|
||||
CATEGORY=$(get_commit_type "$COMMIT_MSG")
|
||||
|
||||
if [ -n "$CATEGORY" ]; then # Only process if it's a conventional commit
|
||||
# Get PR author's GitHub username
|
||||
GITHUB_USERNAME=$(gh pr view "$PR_NUM" --json author --jq '.author.login')
|
||||
|
||||
if [ -n "$GITHUB_USERNAME" ]; then
|
||||
# Check if this is a first-time contributor
|
||||
AUTHOR_EMAIL=$(git show -s --format='%ae' "$HASH")
|
||||
if [ -z "${ALL_AUTHORS[$AUTHOR_EMAIL]}" ]; then
|
||||
NEW_CONTRIBUTORS["$GITHUB_USERNAME"]=1
|
||||
ALL_AUTHORS["$AUTHOR_EMAIL"]=1
|
||||
fi
|
||||
|
||||
CATEGORIES["$CATEGORY"]=1
|
||||
COMMIT_TITLE=${COMMIT_MSG%% (#*} # Remove the PR number suffix
|
||||
COMMIT_TITLE=${COMMIT_TITLE#*: } # Remove the type prefix
|
||||
COMMITS_BY_CATEGORY["$CATEGORY"]+="* $COMMIT_TITLE ([#$PR_NUM](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/pull/$PR_NUM)) by @$GITHUB_USERNAME"$'\n'
|
||||
else
|
||||
COMMIT_TITLE=${COMMIT_MSG%% (#*} # Remove the PR number suffix
|
||||
COMMIT_TITLE=${COMMIT_TITLE#*: } # Remove the type prefix
|
||||
COMMITS_BY_CATEGORY["$CATEGORY"]+="* $COMMIT_TITLE ([#$PR_NUM](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/pull/$PR_NUM))"$'\n'
|
||||
fi
|
||||
fi
|
||||
|
||||
else
|
||||
# echo "Processing as regular commit" >&2
|
||||
# Process conventional commits without PR numbers
|
||||
CATEGORY=$(get_commit_type "$COMMIT_MSG")
|
||||
|
||||
if [ -n "$CATEGORY" ]; then # Only process if it's a conventional commit
|
||||
# Get commit author info
|
||||
AUTHOR_EMAIL=$(git show -s --format='%ae' "$HASH")
|
||||
|
||||
# Try to get GitHub username using gh api
|
||||
if [ -n "$GITHUB_ACTIONS" ] || command -v gh >/dev/null 2>&1; then
|
||||
GITHUB_USERNAME=$(gh api "/repos/${GITHUB_REPOSITORY}/commits/${HASH}" --jq '.author.login' 2>/dev/null)
|
||||
fi
|
||||
|
||||
if [ -n "$GITHUB_USERNAME" ]; then
|
||||
# If we got GitHub username, use it
|
||||
if [ -z "${ALL_AUTHORS[$AUTHOR_EMAIL]}" ]; then
|
||||
NEW_CONTRIBUTORS["$GITHUB_USERNAME"]=1
|
||||
ALL_AUTHORS["$AUTHOR_EMAIL"]=1
|
||||
fi
|
||||
|
||||
CATEGORIES["$CATEGORY"]=1
|
||||
COMMIT_TITLE=${COMMIT_MSG#*: } # Remove the type prefix
|
||||
COMMITS_BY_CATEGORY["$CATEGORY"]+="* $COMMIT_TITLE (${HASH:0:7}) by @$GITHUB_USERNAME"$'\n'
|
||||
else
|
||||
# Fallback to git author name if no GitHub username found
|
||||
AUTHOR_NAME=$(git show -s --format='%an' "$HASH")
|
||||
|
||||
if [ -z "${ALL_AUTHORS[$AUTHOR_EMAIL]}" ]; then
|
||||
NEW_CONTRIBUTORS["$AUTHOR_NAME"]=1
|
||||
ALL_AUTHORS["$AUTHOR_EMAIL"]=1
|
||||
fi
|
||||
|
||||
CATEGORIES["$CATEGORY"]=1
|
||||
COMMIT_TITLE=${COMMIT_MSG#*: } # Remove the type prefix
|
||||
COMMITS_BY_CATEGORY["$CATEGORY"]+="* $COMMIT_TITLE (${HASH:0:7}) by $AUTHOR_NAME"$'\n'
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
done < <(git log "${COMPARE_BASE}..${GITLOG_REF}" --pretty=format:"%H|%s|%b" --reverse --first-parent)
|
||||
|
||||
# Write categorized commits to changelog with their emojis
|
||||
for category in "✨ Features" "🐛 Bug Fixes" "📚 Documentation" "💎 Styles" "♻️ Code Refactoring" "⚡ Performance Improvements" "🧪 Tests" "🛠️ Build System" "⚙️ CI" "🔍 Other Changes"; do
|
||||
if [ -n "${COMMITS_BY_CATEGORY[$category]}" ]; then
|
||||
echo "### $category" >> changelog.md
|
||||
echo "" >> changelog.md
|
||||
echo "${COMMITS_BY_CATEGORY[$category]}" >> changelog.md
|
||||
echo "" >> changelog.md
|
||||
fi
|
||||
done
|
||||
|
||||
# Add first-time contributors section if there are any
|
||||
if [ ${#NEW_CONTRIBUTORS[@]} -gt 0 ]; then
|
||||
echo "## ✨ First-time Contributors" >> changelog.md
|
||||
echo "" >> changelog.md
|
||||
echo "A huge thank you to our amazing new contributors! Your first contribution marks the start of an exciting journey! 🌟" >> changelog.md
|
||||
echo "" >> changelog.md
|
||||
# Use readarray to sort the keys
|
||||
readarray -t sorted_contributors < <(printf '%s\n' "${!NEW_CONTRIBUTORS[@]}" | sort)
|
||||
for github_username in "${sorted_contributors[@]}"; do
|
||||
echo "* 🌟 [@$github_username](https://github.com/$github_username)" >> changelog.md
|
||||
done
|
||||
echo "" >> changelog.md
|
||||
fi
|
||||
|
||||
# Add compare link if not first release
|
||||
if [ -n "$LATEST_TAG" ]; then
|
||||
echo "## 📈 Stats" >> changelog.md
|
||||
echo "" >> changelog.md
|
||||
echo "**Full Changelog**: [\`$LATEST_TAG..v${NEW_VERSION}\`](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/compare/$LATEST_TAG...v${NEW_VERSION})" >> changelog.md
|
||||
fi
|
||||
|
||||
# Output the changelog content
|
||||
CHANGELOG_CONTENT=$(cat changelog.md)
|
||||
{
|
||||
echo "content<<EOF"
|
||||
echo "$CHANGELOG_CONTENT"
|
||||
echo "EOF"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
|
||||
# Also print to stdout for local testing
|
||||
echo "Generated changelog:"
|
||||
echo "==================="
|
||||
cat changelog.md
|
||||
echo "==================="
|
||||
224
.github/workflows/ci.yaml
vendored
224
.github/workflows/ci.yaml
vendored
@ -1,72 +1,248 @@
|
||||
name: CI/CD and Deploy
|
||||
name: CI
|
||||
|
||||
on:
|
||||
# Disabled due to https://linear.app/replay/issue/PRO-1001/nutnew-broken-builds
|
||||
#push:
|
||||
# branches:
|
||||
# - main
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
deployment_status:
|
||||
|
||||
# Cancel in-progress runs when a new commit is pushed
|
||||
concurrency:
|
||||
# For pull requests, use the PR number as the concurrency group
|
||||
# For other events (push, deployment_status), use the branch/ref
|
||||
# This ensures PR builds are cancelled when new commits are pushed
|
||||
# And deployment status events don't interfere with push events for the same branch
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.event.deployment.environment || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
# Define Node.js version in one place
|
||||
env:
|
||||
NODE_VERSION: "22.x"
|
||||
PNPM_VERSION: 8
|
||||
|
||||
jobs:
|
||||
typecheck:
|
||||
name: Type Check
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup and Build
|
||||
uses: ./.github/actions/setup-and-build
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
sentry-auth-token: ${{ github.ref == 'refs/heads/main' && secrets.SENTRY_AUTH_TOKEN || '' }}
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Setup PNPM
|
||||
uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
|
||||
# Use PNPM store cache to improve performance
|
||||
- name: PNPM store cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.pnpm-store
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
# Use node_modules cache to improve performance between runs
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
**/node_modules
|
||||
key: ${{ runner.os }}-modules-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-modules-
|
||||
|
||||
# Install dependencies with fallback for lockfile mismatch
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
# Try frozen install first
|
||||
pnpm install --frozen-lockfile || \
|
||||
# If frozen install fails, update lockfile and try again
|
||||
(echo "Frozen install failed, updating lockfile..." && pnpm install)
|
||||
|
||||
- name: Run type check
|
||||
run: pnpm run typecheck
|
||||
|
||||
lint:
|
||||
name: Lint
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup and Build
|
||||
uses: ./.github/actions/setup-and-build
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
sentry-auth-token: ${{ github.ref == 'refs/heads/main' && secrets.SENTRY_AUTH_TOKEN || '' }}
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Setup PNPM
|
||||
uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
|
||||
# Use PNPM store cache to improve performance
|
||||
- name: PNPM store cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.pnpm-store
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
# Use node_modules cache to improve performance between runs
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
**/node_modules
|
||||
key: ${{ runner.os }}-modules-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-modules-
|
||||
|
||||
# Install dependencies with fallback for lockfile mismatch
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
# Try frozen install first
|
||||
pnpm install --frozen-lockfile || \
|
||||
# If frozen install fails, update lockfile and try again
|
||||
(echo "Frozen install failed, updating lockfile..." && pnpm install)
|
||||
|
||||
- name: Run ESLint
|
||||
run: pnpm run lint
|
||||
|
||||
test:
|
||||
name: Test
|
||||
name: Unit Tests
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup and Build
|
||||
uses: ./.github/actions/setup-and-build
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
sentry-auth-token: ${{ github.ref == 'refs/heads/main' && secrets.SENTRY_AUTH_TOKEN || '' }}
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Setup PNPM
|
||||
uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
|
||||
# Use PNPM store cache to improve performance
|
||||
- name: PNPM store cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.pnpm-store
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
# Use node_modules cache to improve performance between runs
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
**/node_modules
|
||||
key: ${{ runner.os }}-modules-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-modules-
|
||||
|
||||
# Install dependencies with fallback for lockfile mismatch
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
# Try frozen install first
|
||||
pnpm install --frozen-lockfile || \
|
||||
# If frozen install fails, update lockfile and try again
|
||||
(echo "Frozen install failed, updating lockfile..." && pnpm install)
|
||||
|
||||
- name: Run tests
|
||||
run: pnpm run test
|
||||
|
||||
deploy:
|
||||
name: Deploy
|
||||
needs: [typecheck, lint, test]
|
||||
|
||||
playwright:
|
||||
name: Playwright Tests
|
||||
runs-on: ubuntu-latest
|
||||
if: github.ref == 'refs/heads/main'
|
||||
timeout-minutes: 30
|
||||
if: ${{ (github.event_name == 'deployment_status' && github.event.deployment_status.state == 'success') }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup and Build
|
||||
uses: ./.github/actions/setup-and-build
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
sentry-auth-token: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Setup PNPM
|
||||
uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
|
||||
# Use PNPM store cache to improve performance
|
||||
- name: PNPM store cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.pnpm-store
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
# Use node_modules cache to improve performance between runs
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
**/node_modules
|
||||
key: ${{ runner.os }}-modules-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-modules-
|
||||
|
||||
# Install dependencies with fallback for lockfile mismatch
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
# Try frozen install first
|
||||
pnpm install --frozen-lockfile || \
|
||||
# If frozen install fails, update lockfile and try again
|
||||
(echo "Frozen install failed, updating lockfile..." && pnpm install)
|
||||
|
||||
# Cache Playwright browsers to speed up workflow
|
||||
- name: Cache Playwright browsers
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cache/ms-playwright
|
||||
key: ${{ runner.os }}-playwright-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-playwright-
|
||||
|
||||
- name: Install Playwright browsers
|
||||
run: pnpm playwright install chromium
|
||||
|
||||
- name: Get Vercel Preview URL
|
||||
run: |
|
||||
echo "PLAYWRIGHT_TEST_BASE_URL=${{ github.event.deployment_status.target_url }}" >> $GITHUB_ENV
|
||||
echo "Testing against Vercel Preview URL: ${{ github.event.deployment_status.target_url }}"
|
||||
|
||||
- name: Run Playwright tests against Vercel preview
|
||||
if: ${{ github.event_name == 'deployment_status' }}
|
||||
run: pnpm run test:e2e
|
||||
|
||||
- name: Upload test results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: playwright-report
|
||||
path: playwright-report/
|
||||
retention-days: 30
|
||||
|
||||
81
.github/workflows/docker.yaml
vendored
81
.github/workflows/docker.yaml
vendored
@ -1,81 +0,0 @@
|
||||
---
|
||||
name: Docker Publish
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
tags:
|
||||
- v*
|
||||
- "*"
|
||||
|
||||
permissions:
|
||||
packages: write
|
||||
contents: read
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
DOCKER_IMAGE: ghcr.io/${{ github.repository }}
|
||||
BUILD_TARGET: bolt-ai-production # bolt-ai-development
|
||||
|
||||
jobs:
|
||||
docker-build-publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- id: string
|
||||
uses: ASzc/change-string-case-action@v6
|
||||
with:
|
||||
string: ${{ env.DOCKER_IMAGE }}
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: crazy-max/ghaction-docker-meta@v5
|
||||
with:
|
||||
images: ${{ steps.string.outputs.lowercase }}
|
||||
flavor: |
|
||||
latest=true
|
||||
prefix=
|
||||
suffix=
|
||||
tags: |
|
||||
type=semver,pattern={{version}}
|
||||
type=pep440,pattern={{version}}
|
||||
type=ref,event=tag
|
||||
type=raw,value={{sha}}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }} # ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }} # ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
target: ${{ env.BUILD_TARGET }}
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=registry,ref=${{ steps.string.outputs.lowercase }}:latest
|
||||
cache-to: type=inline
|
||||
|
||||
- name: Check manifest
|
||||
run: |
|
||||
docker buildx imagetools inspect ${{ steps.string.outputs.lowercase }}:${{ steps.meta.outputs.version }}
|
||||
|
||||
- name: Dump context
|
||||
if: always()
|
||||
uses: crazy-max/ghaction-dump-context@v2
|
||||
35
.github/workflows/docs.yaml
vendored
35
.github/workflows/docs.yaml
vendored
@ -1,35 +0,0 @@
|
||||
name: Docs CI/CD
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'docs/**' # This will only trigger the workflow when files in docs directory change
|
||||
permissions:
|
||||
contents: write
|
||||
jobs:
|
||||
build_docs:
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./docs
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Configure Git Credentials
|
||||
run: |
|
||||
git config user.name github-actions[bot]
|
||||
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.x
|
||||
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
key: mkdocs-material-${{ env.cache_id }}
|
||||
path: .cache
|
||||
restore-keys: |
|
||||
mkdocs-material-
|
||||
|
||||
- run: pip install mkdocs-material
|
||||
- run: mkdocs gh-deploy --force
|
||||
46
.github/workflows/playwright.yml
vendored
46
.github/workflows/playwright.yml
vendored
@ -1,46 +0,0 @@
|
||||
name: Playwright Tests
|
||||
|
||||
on:
|
||||
deployment_status:
|
||||
jobs:
|
||||
test:
|
||||
name: 'Playwright Tests'
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name == 'pull_request' || (github.event_name == 'deployment_status' && github.event.deployment_status.state == 'success') }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '18'
|
||||
|
||||
- name: Set up pnpm
|
||||
uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: 9.4.0
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Install Playwright browsers
|
||||
run: npx playwright install chromium
|
||||
|
||||
- name: Get Vercel Preview URL
|
||||
if: ${{ github.event_name == 'deployment_status' }}
|
||||
run: |
|
||||
echo "PLAYWRIGHT_TEST_BASE_URL=${{ github.event.deployment_status.target_url }}" >> $GITHUB_ENV
|
||||
echo "Testing against Vercel Preview URL: ${{ github.event.deployment_status.target_url }}"
|
||||
|
||||
- name: Run Playwright tests
|
||||
if: ${{ github.event_name == 'deployment_status' }}
|
||||
run: npx playwright test
|
||||
|
||||
- name: Upload test results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: playwright-report
|
||||
path: playwright-report/
|
||||
retention-days: 30
|
||||
31
.github/workflows/pr-release-validation.yaml
vendored
31
.github/workflows/pr-release-validation.yaml
vendored
@ -1,31 +0,0 @@
|
||||
name: PR Validation
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, labeled, unlabeled]
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Validate PR Labels
|
||||
run: |
|
||||
if [[ "${{ contains(github.event.pull_request.labels.*.name, 'stable-release') }}" == "true" ]]; then
|
||||
echo "✓ PR has stable-release label"
|
||||
|
||||
# Check version bump labels
|
||||
if [[ "${{ contains(github.event.pull_request.labels.*.name, 'major') }}" == "true" ]]; then
|
||||
echo "✓ Major version bump requested"
|
||||
elif [[ "${{ contains(github.event.pull_request.labels.*.name, 'minor') }}" == "true" ]]; then
|
||||
echo "✓ Minor version bump requested"
|
||||
else
|
||||
echo "✓ Patch version bump will be applied"
|
||||
fi
|
||||
else
|
||||
echo "This PR doesn't have the stable-release label. No release will be created."
|
||||
fi
|
||||
32
.github/workflows/semantic-pr.yaml
vendored
32
.github/workflows/semantic-pr.yaml
vendored
@ -1,32 +0,0 @@
|
||||
name: Semantic Pull Request
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, reopened, edited, synchronize]
|
||||
permissions:
|
||||
pull-requests: read
|
||||
jobs:
|
||||
main:
|
||||
name: Validate PR Title
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# https://github.com/amannn/action-semantic-pull-request/releases/tag/v5.5.3
|
||||
- uses: amannn/action-semantic-pull-request@0723387faaf9b38adef4775cd42cfd5155ed6017
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
subjectPattern: ^(?![A-Z]).+$
|
||||
subjectPatternError: |
|
||||
The subject "{subject}" found in the pull request title "{title}"
|
||||
didn't match the configured pattern. Please ensure that the subject
|
||||
doesn't start with an uppercase character.
|
||||
types: |
|
||||
fix
|
||||
feat
|
||||
chore
|
||||
build
|
||||
ci
|
||||
perf
|
||||
docs
|
||||
refactor
|
||||
revert
|
||||
test
|
||||
25
.github/workflows/stale.yml
vendored
25
.github/workflows/stale.yml
vendored
@ -1,25 +0,0 @@
|
||||
name: Mark Stale Issues and Pull Requests
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 2 * * *' # Runs daily at 2:00 AM UTC
|
||||
workflow_dispatch: # Allows manual triggering of the workflow
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Mark stale issues and pull requests
|
||||
uses: actions/stale@v8
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
stale-issue-message: "This issue has been marked as stale due to inactivity. If no further activity occurs, it will be closed in 7 days."
|
||||
stale-pr-message: "This pull request has been marked as stale due to inactivity. If no further activity occurs, it will be closed in 7 days."
|
||||
days-before-stale: 10 # Number of days before marking an issue or PR as stale
|
||||
days-before-close: 4 # Number of days after being marked stale before closing
|
||||
stale-issue-label: "stale" # Label to apply to stale issues
|
||||
stale-pr-label: "stale" # Label to apply to stale pull requests
|
||||
exempt-issue-labels: "pinned,important" # Issues with these labels won't be marked stale
|
||||
exempt-pr-labels: "pinned,important" # PRs with these labels won't be marked stale
|
||||
operations-per-run: 75 # Limits the number of actions per run to avoid API rate limits
|
||||
126
.github/workflows/update-stable.yml
vendored
126
.github/workflows/update-stable.yml
vendored
@ -1,126 +0,0 @@
|
||||
name: Update Stable Branch
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
prepare-release:
|
||||
if: contains(github.event.head_commit.message, '#release')
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Configure Git
|
||||
run: |
|
||||
git config --global user.name 'github-actions[bot]'
|
||||
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: latest
|
||||
run_install: false
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
shell: bash
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Setup pnpm cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
- name: Get Current Version
|
||||
id: current_version
|
||||
run: |
|
||||
CURRENT_VERSION=$(node -p "require('./package.json').version")
|
||||
echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Install semver
|
||||
run: pnpm add -g semver
|
||||
|
||||
- name: Determine Version Bump
|
||||
id: version_bump
|
||||
run: |
|
||||
COMMIT_MSG="${{ github.event.head_commit.message }}"
|
||||
if [[ $COMMIT_MSG =~ "#release:major" ]]; then
|
||||
echo "bump=major" >> $GITHUB_OUTPUT
|
||||
elif [[ $COMMIT_MSG =~ "#release:minor" ]]; then
|
||||
echo "bump=minor" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "bump=patch" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Bump Version
|
||||
id: bump_version
|
||||
run: |
|
||||
NEW_VERSION=$(semver -i ${{ steps.version_bump.outputs.bump }} ${{ steps.current_version.outputs.version }})
|
||||
echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Update Package.json
|
||||
run: |
|
||||
NEW_VERSION=${{ steps.bump_version.outputs.new_version }}
|
||||
pnpm version $NEW_VERSION --no-git-tag-version --allow-same-version
|
||||
|
||||
|
||||
- name: Prepare changelog script
|
||||
run: chmod +x .github/scripts/generate-changelog.sh
|
||||
|
||||
- name: Generate Changelog
|
||||
id: changelog
|
||||
env:
|
||||
NEW_VERSION: ${{ steps.bump_version.outputs.new_version }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
run: .github/scripts/generate-changelog.sh
|
||||
|
||||
- name: Get the latest commit hash and version tag
|
||||
run: |
|
||||
echo "COMMIT_HASH=$(git rev-parse HEAD)" >> $GITHUB_ENV
|
||||
echo "NEW_VERSION=${{ steps.bump_version.outputs.new_version }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Commit and Tag Release
|
||||
run: |
|
||||
git pull
|
||||
git add package.json pnpm-lock.yaml changelog.md
|
||||
git commit -m "chore: release version ${{ steps.bump_version.outputs.new_version }}"
|
||||
git tag "v${{ steps.bump_version.outputs.new_version }}"
|
||||
git push
|
||||
git push --tags
|
||||
|
||||
- name: Update Stable Branch
|
||||
run: |
|
||||
if ! git checkout stable 2>/dev/null; then
|
||||
echo "Creating new stable branch..."
|
||||
git checkout -b stable
|
||||
fi
|
||||
git merge main --no-ff -m "chore: release version ${{ steps.bump_version.outputs.new_version }}"
|
||||
git push --set-upstream origin stable --force
|
||||
|
||||
- name: Create GitHub Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
VERSION="v${{ steps.bump_version.outputs.new_version }}"
|
||||
gh release create "$VERSION" \
|
||||
--title "Release $VERSION" \
|
||||
--notes "${{ steps.changelog.outputs.content }}" \
|
||||
--target stable
|
||||
Loading…
Reference in New Issue
Block a user