* refactor: extract windmill-api-scripts and windmill-api-users subcrates Split the monolithic windmill-api crate by extracting scripts.rs, flows.rs, users.rs, and users_oss.rs into dedicated subcrates. This reduces incremental rebuild times when editing these modules. Changes: - Create windmill-api-scripts crate (scripts.rs + flows.rs, ~4.3K lines) - Create windmill-api-users crate (users.rs + users_oss.rs, ~2.4K lines) - Move clear_schedule to windmill-queue (shared by scripts, flows, workspaces) - Move username utilities (VALID_USERNAME, INVALID_USERNAME_CHARS, generate_instance_wide_unique_username) to windmill-common/src/usernames.rs - Move COOKIE_DOMAIN, IS_SECURE, WithStarredInfoQuery, BulkDeleteRequest, WebhookShared to windmill-common for cross-crate access - Original files in windmill-api become thin stubs with pub use re-exports - EE-dependent route handlers remain in windmill-api (create_user, rename_user, set_password, reset_password, etc.) - Feature forwarding for enterprise, private, parquet, no_auth Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: extract windmill-api-workspaces subcrate (Step 3) Move workspaces.rs, workspaces_extra.rs, workspaces_oss.rs, and workspaces_ee.rs into a new windmill-api-workspaces crate (~7K lines). Routes that depend on windmill-api internals (AI copilot, teams, tarball export, critical alerts, stripe) remain in the windmill-api stub. The subcrate handles all other workspace management routes. Also moved send_email_if_possible to windmill-common/email_oss.rs to make it available across subcrates without circular deps. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * all * refactor: extract windmill-api-groups subcrate (groups.rs + folders.rs) Extract groups.rs (1,093 lines) and folders.rs (833 lines) into a new windmill-api-groups subcrate. Both modules had clean dependencies on already-extracted crates (windmill-api-auth, windmill-common, windmill-api-workspaces). Also removes unused re-exports of get_instance_username_or_create_pending and INVALID_USERNAME_CHARS from windmill-api/src/utils.rs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: add granular_acls.rs and folder_history.rs to windmill-api-groups Extract granular_acls.rs (395 lines) and folder_history.rs (68 lines) into the windmill-api-groups subcrate. Both modules only depend on already-extracted crates and belong to the same access-control domain as groups and folders. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: remove unused imports and dead code from subcrate extraction - Remove unused BASE_URL import from lib.rs - Remove workspaces_extra.rs and workspaces_oss.rs re-export stubs (no consumers in windmill-api) - Remove dead send_email_if_possible OSS stub (callers moved to windmill-api-users) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * all * chore: bust CI cargo cache for subcrate split Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: re-export BASE_URL for EE files that use crate::BASE_URL Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: forward no_auth feature to windmill-api-users, remove dead code - Add "windmill-api-users/no_auth" to windmill-api's no_auth feature so the login bypass in users.rs:1600 activates correctly - Remove dead send_email_if_possible from windmill-api-users/users_oss.rs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: re-enable cargo cache for backend tests Cache was disabled to bust stale entries from before subcrate split. Now that a clean build has run, re-enable for faster CI. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: install mold+clang in CI workflows The .cargo/config.toml uses mold linker for x86_64-linux. Build scripts require linking even during cargo check. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: increase cargo test timeout to 30 min Exit code 143 (SIGTERM) means the 20-min timeout was hit during compilation without cache. Bump to 30 min as safety net. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: limit cargo build jobs to 4 to prevent OOM in CI Exit code 143 (SIGTERM) after 8 min = OOM kill during compilation. 8 parallel LLVM codegen jobs exhaust memory on ubicloud-standard-8. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
225 lines
8.0 KiB
YAML
225 lines
8.0 KiB
YAML
name: Backend only integration tests
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- "main"
|
|
paths:
|
|
- "backend/**"
|
|
- ".github/workflows/backend-test.yml"
|
|
pull_request:
|
|
types: [opened, synchronize, reopened]
|
|
paths:
|
|
- "backend/**"
|
|
- ".github/workflows/backend-test.yml"
|
|
|
|
defaults:
|
|
run:
|
|
working-directory: ./backend
|
|
|
|
jobs:
|
|
cargo_test:
|
|
runs-on: ubicloud-standard-8
|
|
services:
|
|
postgres:
|
|
image: postgres
|
|
ports:
|
|
- 5432:5432
|
|
env:
|
|
POSTGRES_DB: windmill
|
|
POSTGRES_PASSWORD: changeme
|
|
options: >-
|
|
--health-cmd pg_isready --health-interval 10s --health-timeout 5s
|
|
--health-retries 5
|
|
mysql:
|
|
image: mysql:8.0
|
|
ports:
|
|
- 3306:3306
|
|
env:
|
|
MYSQL_ROOT_PASSWORD: changeme
|
|
MYSQL_DATABASE: windmill_test
|
|
options: >-
|
|
--health-cmd "mysqladmin ping -h localhost" --health-interval 10s
|
|
--health-timeout 5s --health-retries 5
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-dotnet@v4
|
|
with:
|
|
dotnet-version: "9.0.x"
|
|
- uses: denoland/setup-deno@v2
|
|
with:
|
|
deno-version: v2.x
|
|
- uses: actions/setup-go@v2
|
|
with:
|
|
go-version: 1.21.5
|
|
- uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: 1.3.8
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '20'
|
|
- uses: astral-sh/setup-uv@v6.2.1
|
|
with:
|
|
version: "0.9.24"
|
|
- uses: shivammathur/setup-php@v2
|
|
with:
|
|
php-version: '8.3'
|
|
tools: composer
|
|
- uses: ruby/setup-ruby@v1
|
|
with:
|
|
ruby-version: '3.3'
|
|
bundler-cache: false
|
|
- name: Install PowerShell, mold and clang
|
|
run: |
|
|
sudo apt-get update && sudo apt-get install -y powershell mold clang
|
|
working-directory: /
|
|
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
|
with:
|
|
cache-workspaces: backend
|
|
toolchain: 1.90.0
|
|
- name: Read EE repo commit hash
|
|
run: |
|
|
echo "ee_repo_ref=$(cat ./ee-repo-ref.txt)" >> "$GITHUB_ENV"
|
|
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
repository: windmill-labs/windmill-ee-private
|
|
path: ./windmill-ee-private
|
|
ref: ${{ env.ee_repo_ref }}
|
|
token: ${{ secrets.WINDMILL_EE_PRIVATE_ACCESS }}
|
|
fetch-depth: 0
|
|
|
|
- name: Substitute EE code (EE logic is behind feature flag)
|
|
run: |
|
|
./substitute_ee_code.sh --copy --dir ./windmill-ee-private
|
|
- name: Setup private npm registry with test package
|
|
working-directory: /tmp
|
|
run: |
|
|
set -e
|
|
|
|
# Install Verdaccio globally
|
|
npm install -g verdaccio
|
|
|
|
# Create Verdaccio config that requires authentication for @windmill-test packages
|
|
mkdir -p /tmp/verdaccio/storage
|
|
cat > /tmp/verdaccio/config.yaml << 'VERDACCIO_CONFIG'
|
|
storage: /tmp/verdaccio/storage
|
|
auth:
|
|
htpasswd:
|
|
file: /tmp/verdaccio/htpasswd
|
|
max_users: 100
|
|
uplinks:
|
|
npmjs:
|
|
url: https://registry.npmjs.org/
|
|
packages:
|
|
'@windmill-test/*':
|
|
access: $authenticated
|
|
publish: $authenticated
|
|
'@*/*':
|
|
access: $all
|
|
publish: $authenticated
|
|
proxy: npmjs
|
|
'**':
|
|
access: $all
|
|
publish: $authenticated
|
|
proxy: npmjs
|
|
server:
|
|
keepAliveTimeout: 60
|
|
middlewares:
|
|
audit:
|
|
enabled: true
|
|
log: { type: stdout, format: pretty, level: warn }
|
|
VERDACCIO_CONFIG
|
|
|
|
# Create empty htpasswd file (users will be created via API)
|
|
touch /tmp/verdaccio/htpasswd
|
|
|
|
# Start Verdaccio in background
|
|
verdaccio --config /tmp/verdaccio/config.yaml &
|
|
VERDACCIO_PID=$!
|
|
|
|
# Wait for Verdaccio to be ready
|
|
echo "Waiting for Verdaccio to start..."
|
|
for i in {1..30}; do
|
|
if curl -s http://localhost:4873/-/ping > /dev/null 2>&1; then
|
|
echo "Verdaccio is ready"
|
|
break
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
# Login to get a token
|
|
echo "Getting auth token..."
|
|
RESPONSE=$(curl -s -X PUT \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"name":"testuser","password":"testpass123"}' \
|
|
http://localhost:4873/-/user/org.couchdb.user:testuser)
|
|
|
|
echo "Auth response: $RESPONSE"
|
|
NPM_TOKEN=$(echo "$RESPONSE" | jq -r '.token')
|
|
|
|
if [ -z "$NPM_TOKEN" ] || [ "$NPM_TOKEN" = "null" ]; then
|
|
echo "Failed to get NPM token from response"
|
|
exit 1
|
|
fi
|
|
|
|
echo "NPM_TOKEN=${NPM_TOKEN}" >> $GITHUB_ENV
|
|
echo "Got NPM token successfully: ${NPM_TOKEN:0:10}..."
|
|
|
|
# Configure npm globally with the auth token
|
|
echo "//localhost:4873/:_authToken=${NPM_TOKEN}" > ~/.npmrc
|
|
echo "Configured ~/.npmrc with auth token"
|
|
|
|
# Create a simple test package
|
|
mkdir -p /tmp/windmill-test-private-pkg
|
|
cat > /tmp/windmill-test-private-pkg/package.json << 'PKG_JSON'
|
|
{
|
|
"name": "@windmill-test/private-pkg",
|
|
"version": "1.0.0",
|
|
"main": "index.js"
|
|
}
|
|
PKG_JSON
|
|
cat > /tmp/windmill-test-private-pkg/index.js << 'PKG_JS'
|
|
module.exports.greet = (name) => `Hello from private package, ${name}!`;
|
|
PKG_JS
|
|
|
|
# Publish to Verdaccio with auth
|
|
cd /tmp/windmill-test-private-pkg
|
|
echo "Publishing package..."
|
|
npm publish --registry http://localhost:4873
|
|
echo "Package published successfully"
|
|
|
|
# Verify the package requires auth by trying anonymous access (should fail)
|
|
rm -f ~/.npmrc
|
|
echo "Testing anonymous access (should fail)..."
|
|
if npm view @windmill-test/private-pkg --registry http://localhost:4873 2>/dev/null; then
|
|
echo "ERROR: Package should require authentication but anonymous access worked"
|
|
exit 1
|
|
fi
|
|
echo "Verified: Package requires authentication for @windmill-test/private-pkg"
|
|
- name: Cache DuckDB FFI module build
|
|
uses: actions/cache@v3
|
|
with:
|
|
path: ./backend/windmill-duckdb-ffi-internal/target
|
|
key: ${{ runner.os }}-duckdb-ffi-${{ hashFiles('./backend/windmill-duckdb-ffi-internal/src/**/*.rs', './backend/windmill-duckdb-ffi-internal/Cargo.toml', './backend/windmill-duckdb-ffi-internal/Cargo.lock') }}
|
|
restore-keys: |
|
|
${{ runner.os }}-duckdb-ffi-
|
|
- name: cargo test
|
|
timeout-minutes: 30
|
|
env:
|
|
SQLX_OFFLINE: true
|
|
DATABASE_URL: postgres://postgres:changeme@localhost:5432/windmill
|
|
DISABLE_EMBEDDING: true
|
|
RUST_LOG: info
|
|
RUST_LOG_STYLE: never
|
|
CARGO_NET_GIT_FETCH_WITH_CLI: true
|
|
CARGO_BUILD_JOBS: 4
|
|
WMDEBUG_FORCE_V0_WORKSPACE_DEPENDENCIES: 1
|
|
WMDEBUG_FORCE_RUNNABLE_SETTINGS_V0: 1
|
|
WMDEBUG_FORCE_NO_LEGACY_DEBOUNCING_COMPAT: 1
|
|
TEST_NPM_REGISTRY: "http://localhost:4873/:_authToken=${{ env.NPM_TOKEN }}"
|
|
run: |
|
|
deno --version && bun -v && node --version && go version && python3 --version && php --version && ruby --version && pwsh --version && dotnet --version
|
|
cd windmill-duckdb-ffi-internal && ./build_dev.sh && cd ..
|
|
DENO_PATH=$(which deno) BUN_PATH=$(which bun) NODE_BIN_PATH=$(which node) GO_PATH=$(which go) UV_PATH=$(which uv) PHP_PATH=$(which php) COMPOSER_PATH=$(which composer) RUBY_PATH=$(which ruby) BUNDLE_PATH=$(which bundle) GEM_PATH=$(which gem) POWERSHELL_PATH=$(which pwsh) DOTNET_PATH=$(which dotnet) cargo test --features enterprise,deno_core,duckdb,license,python,rust,scoped_cache,parquet,private,private_registry_test,csharp,php,ruby,mysql --all -- --nocapture
|