Skip to content

Commit bc98dac

Browse files
committed
Merge branch 'main' into puter-js-tests
2 parents b593eb5 + f004452 commit bc98dac

1,586 files changed

Lines changed: 138142 additions & 162598 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.dockerignore

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,40 @@
11
.dockerignore
22
Dockerfile
3+
docker-compose.yml
4+
5+
# Dev / build artifacts (recreated inside the build stage)
36
node_modules
7+
dist
8+
src/gui/dist
9+
src/puter-js/dist
10+
*.tsbuildinfo
11+
12+
# Local runtime data
13+
volatile
14+
config.json
15+
config.dev.json
416
/puter
17+
18+
# OS / editor
19+
.DS_Store
20+
.vscode
21+
.idea
22+
23+
# Git / CI
24+
.git
25+
.github
26+
27+
# Logs
28+
*.log
29+
npm-debug.log*
30+
.npm
31+
32+
# Tests / coverage
33+
coverage
34+
.nyc_output
35+
36+
# Secrets
37+
.env
38+
.env.*
39+
creds*
40+
*.pem

.env.example

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,18 @@
1-
PORT=4000
1+
# Copy this file to `.env`, fill in the secrets, and `docker compose -f
2+
# docker-compose.full.yml up -d`. None of the defaults below are safe for
3+
# anything beyond a local laptop test.
4+
5+
# ── Public-facing ports (nginx) ---------------------------------------
6+
HTTP_PORT=80
7+
# HTTPS_PORT=443 # uncomment after you enable TLS in nginx/nginx.conf
8+
9+
# ── MariaDB ------------------------------------------------------------
10+
MARIADB_ROOT_PASSWORD=replace-with-strong-password
11+
MARIADB_DATABASE=puter
12+
MARIADB_USER=puter
13+
MARIADB_PASSWORD=replace-with-strong-password
14+
15+
# ── S3 (RustFS) --------------------------------------------------------
16+
S3_ACCESS_KEY=puter
17+
S3_SECRET_KEY=replace-with-strong-secret
18+
S3_BUCKET=puter-local
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: AI Provider Integration Tests
2+
3+
# Hits real provider APIs with cheap models, so this workflow is
4+
# manually triggered only. Each provider's test reads its credential
5+
# from PUTER_TEST_AI_<PROVIDER>_API_KEY and skips itself silently if
6+
# the secret is missing.
7+
8+
on:
9+
workflow_dispatch:
10+
11+
permissions:
12+
contents: read
13+
14+
jobs:
15+
ai-test:
16+
runs-on: ubuntu-latest
17+
18+
steps:
19+
- name: Checkout repository
20+
uses: actions/checkout@v4
21+
22+
- name: Set up Node.js
23+
uses: actions/setup-node@v4
24+
with:
25+
node-version: '24'
26+
cache: 'npm'
27+
28+
- name: Install dependencies
29+
run: npm ci
30+
31+
- name: Run AI provider integration tests
32+
# Vitest treats positional args as filename substring filters.
33+
# The pattern matches every `*.integration.test.ts` file and
34+
# nothing else — the regular backend test suite stays out.
35+
run: npm run test:backend -- integration.test
36+
env:
37+
CI: 'true'
38+
PUTER_TEST_AI_CLAUDE_API_KEY: ${{ secrets.PUTER_TEST_AI_CLAUDE_API_KEY }}
39+
PUTER_TEST_AI_OPENAI_API_KEY: ${{ secrets.PUTER_TEST_AI_OPENAI_API_KEY }}
40+
PUTER_TEST_AI_GEMINI_API_KEY: ${{ secrets.PUTER_TEST_AI_GEMINI_API_KEY }}
41+
PUTER_TEST_AI_GROQ_API_KEY: ${{ secrets.PUTER_TEST_AI_GROQ_API_KEY }}
42+
PUTER_TEST_AI_MISTRAL_API_KEY: ${{ secrets.PUTER_TEST_AI_MISTRAL_API_KEY }}
43+
PUTER_TEST_AI_DEEPSEEK_API_KEY: ${{ secrets.PUTER_TEST_AI_DEEPSEEK_API_KEY }}
44+
PUTER_TEST_AI_XAI_API_KEY: ${{ secrets.PUTER_TEST_AI_XAI_API_KEY }}
45+
PUTER_TEST_AI_OPENROUTER_API_KEY: ${{ secrets.PUTER_TEST_AI_OPENROUTER_API_KEY }}
46+
PUTER_TEST_AI_TOGETHER_API_KEY: ${{ secrets.PUTER_TEST_AI_TOGETHER_API_KEY }}
47+
PUTER_TEST_AI_MOONSHOT_API_KEY: ${{ secrets.PUTER_TEST_AI_MOONSHOT_API_KEY }}
48+
PUTER_TEST_AI_ZAI_API_KEY: ${{ secrets.PUTER_TEST_AI_ZAI_API_KEY }}
49+
PUTER_TEST_AI_ELEVENLABS_API_KEY: ${{ secrets.PUTER_TEST_AI_ELEVENLABS_API_KEY }}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
name: Backend Tests
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize, reopened]
6+
7+
permissions:
8+
contents: read
9+
pull-requests: write
10+
11+
jobs:
12+
test:
13+
runs-on: ubuntu-latest
14+
strategy:
15+
fail-fast: false
16+
matrix:
17+
include:
18+
- ref: ${{ github.base_ref }}
19+
artifact: base
20+
- ref: ${{ github.head_ref }}
21+
artifact: pr
22+
23+
steps:
24+
- name: Checkout ${{ matrix.ref }}
25+
uses: actions/checkout@v4
26+
with:
27+
ref: ${{ matrix.ref }}
28+
repository: ${{ github.event.pull_request.head.repo.full_name }}
29+
30+
- name: Set up Node.js
31+
uses: actions/setup-node@v4
32+
with:
33+
node-version: '24'
34+
cache: 'npm'
35+
36+
- name: Install dependencies
37+
run: npm ci
38+
39+
- name: Run backend tests with coverage
40+
run: npm run test:backend -- --coverage
41+
env:
42+
CI: 'true'
43+
44+
- name: Upload coverage artifact
45+
if: always()
46+
uses: actions/upload-artifact@v4
47+
with:
48+
name: backend-coverage-${{ matrix.artifact }}
49+
path: src/backend/coverage/
50+
retention-days: 14
51+
52+
report-coverage:
53+
needs: test
54+
if: always()
55+
runs-on: ubuntu-latest
56+
steps:
57+
- name: Checkout repository
58+
uses: actions/checkout@v4
59+
60+
- name: Download PR coverage
61+
uses: actions/download-artifact@v4
62+
with:
63+
name: backend-coverage-pr
64+
path: src/backend/coverage
65+
66+
- name: Download base coverage
67+
uses: actions/download-artifact@v4
68+
with:
69+
name: backend-coverage-base
70+
path: coverage-base
71+
72+
- name: Report coverage on PR
73+
uses: davelosert/vitest-coverage-report-action@v2
74+
with:
75+
json-summary-path: src/backend/coverage/coverage-summary.json
76+
json-final-path: src/backend/coverage/coverage-final.json
77+
json-summary-compare-path: coverage-base/coverage-summary.json
Lines changed: 87 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,101 @@
1-
#
21
name: Docker Image CI
32

4-
# Configures this workflow to run every time a change is pushed to the
5-
# branch called `main`.
3+
# Two ways in:
4+
# - push of a calver tag (YY.MM or YY.MM.p) → publishes <version>, latest, main
5+
# - workflow_dispatch → publishes latest + main from whichever ref the user
6+
# picks in the Actions UI. Used to fast-forward :latest/:main when the
7+
# branch has moved ahead of the most recent release tag.
68
on:
7-
push:
8-
tags:
9-
- '*.*.*'
10-
branches:
11-
- 'main'
9+
push:
10+
tags:
11+
- '[0-9][0-9].[0-9][0-9]'
12+
- '[0-9][0-9].[0-9][0-9].[0-9]*'
13+
workflow_dispatch:
14+
inputs:
15+
push_latest:
16+
description: 'Push :latest tag'
17+
type: boolean
18+
default: true
19+
push_main:
20+
description: 'Push :main tag'
21+
type: boolean
22+
default: true
1223

13-
# Defines two custom environment variables for the workflow. These are used
14-
# for the Container registry domain, and a name for the Docker image that
15-
# this workflow builds.
1624
env:
17-
REGISTRY: ghcr.io
18-
IMAGE_NAME: ${{ github.repository }}
25+
REGISTRY: ghcr.io
26+
IMAGE_NAME: ${{ github.repository }}
1927

20-
# There is a single job in this workflow. It's configured to run on the
21-
# latest available version of Ubuntu.
2228
jobs:
23-
build-and-push-image:
24-
runs-on: ubuntu-latest
29+
build-and-push-image:
30+
runs-on: ubuntu-latest
2531

26-
# Sets the permissions granted to the `GITHUB_TOKEN` for the actions
27-
# in this job.
28-
permissions:
29-
contents: read
30-
packages: write
32+
permissions:
33+
contents: read
34+
packages: write
3135

32-
steps:
33-
- name: Checkout repository
34-
uses: actions/checkout@v4
36+
steps:
37+
- name: Validate calver tag
38+
if: github.event_name == 'push'
39+
env:
40+
REF_NAME: ${{ github.ref_name }}
41+
run: |
42+
if ! [[ "$REF_NAME" =~ ^[0-9]{2}\.[0-9]{2}(\.[0-9]+)?$ ]]; then
43+
echo "Tag '$REF_NAME' does not match YY.MM or YY.MM.p calver format."
44+
exit 1
45+
fi
3546
36-
# Uses the `docker/login-action` action to log in to the Container
37-
# registry using the account and password that will publish the packages.
38-
# Once published, the packages are scoped to the account defined here.
39-
- name: Log in to GitHub Package Container registry
40-
uses: docker/login-action@v3
41-
with:
42-
registry: ${{ env.REGISTRY }}
43-
username: ${{ github.actor }}
44-
password: ${{ secrets.GITHUB_TOKEN }}
47+
- name: Checkout repository
48+
uses: actions/checkout@v4
4549

46-
- name: Set up QEMU
47-
uses: docker/setup-qemu-action@v3
50+
- name: Log in to GitHub Package Container registry
51+
uses: docker/login-action@v3
52+
with:
53+
registry: ${{ env.REGISTRY }}
54+
username: ${{ github.actor }}
55+
password: ${{ secrets.GITHUB_TOKEN }}
4856

49-
- name: Set up Docker Buildx
50-
uses: docker/setup-buildx-action@v3
57+
- name: Log in to Docker Hub
58+
uses: docker/login-action@v3
59+
with:
60+
username: ${{ secrets.DOCKERHUB_USERNAME }}
61+
password: ${{ secrets.DOCKERHUB_TOKEN }}
5162

52-
# This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about)
53-
# to extract tags and labels that will be applied to the specified image.
54-
# The `id` "meta" allows the output of this step to be referenced in
55-
# a subsequent step. The `images` value provides the base name for the
56-
# tags and labels.
57-
- name: Extract metadata (tags, labels) for Docker
58-
id: meta
59-
uses: docker/metadata-action@v5
60-
with:
61-
images: "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}"
62-
tags: |
63-
type=semver,pattern={{version}}
64-
type=ref,event=branch
63+
- name: Set up QEMU
64+
uses: docker/setup-qemu-action@v3
6565

66-
# This step uses the `docker/build-push-action` action to build the
67-
# image, based on your repository's `Dockerfile`. If the build succeeds,
68-
# it pushes the image to GitHub Packages.
69-
# It uses the `context` parameter to define the build's context as the
70-
# set of files located in the specified path. For more information, see
71-
# "[Usage](https://github.com/docker/build-push-action#usage)" in the
72-
# README of the `docker/build-push-action` repository.
73-
# It uses the `tags` and `labels` parameters to tag and label the image
74-
# with the output from the "meta" step.
75-
- name: Build and push Docker image
76-
uses: docker/build-push-action@v5
77-
with:
78-
platforms: linux/amd64,linux/arm64
79-
context: .
80-
push: ${{ github.event_name != 'pull_request' }}
81-
tags: ${{ steps.meta.outputs.tags }}
82-
labels: ${{ steps.meta.outputs.labels }}
83-
cache-from: type=gha
84-
cache-to: type=gha,mode=max
66+
- name: Set up Docker Buildx
67+
uses: docker/setup-buildx-action@v3
68+
69+
- name: Extract metadata (tags, labels) for Docker
70+
id: meta
71+
uses: docker/metadata-action@v5
72+
with:
73+
images: |
74+
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
75+
heyputer/puter
76+
# type=ref,event=tag only emits on tag pushes, so manual runs skip
77+
# the calver tag and just publish whichever of latest / main the
78+
# dispatch inputs asked for. On a tag push, both default to true.
79+
tags: |
80+
type=ref,event=tag
81+
type=raw,value=latest,enable=${{ github.event_name == 'push' || inputs.push_latest }}
82+
type=raw,value=main,enable=${{ github.event_name == 'push' || inputs.push_main }}
83+
84+
- name: Build and push Docker image
85+
uses: docker/build-push-action@v5
86+
with:
87+
platforms: linux/amd64,linux/arm64
88+
context: .
89+
push: true
90+
tags: ${{ steps.meta.outputs.tags }}
91+
labels: ${{ steps.meta.outputs.labels }}
92+
cache-from: type=gha
93+
cache-to: type=gha,mode=max
94+
95+
- name: Sync README to Docker Hub
96+
uses: peter-evans/dockerhub-description@v4
97+
with:
98+
username: ${{ secrets.DOCKERHUB_USERNAME }}
99+
password: ${{ secrets.DOCKERHUB_TOKEN }}
100+
repository: heyputer/puter
101+
readme-filepath: ./README.md

0 commit comments

Comments
 (0)