Compare commits

..

No commits in common. "develop" and "v2.2.0-beta.1" have entirely different histories.

27 changed files with 2411 additions and 501 deletions

View file

@ -382,24 +382,6 @@
"contributions": [
"code"
]
},
{
"login": "0livier",
"name": "Olivier Garcia",
"avatar_url": "https://avatars.githubusercontent.com/u/10607?v=4",
"profile": "https://github.com/0livier",
"contributions": [
"code"
]
},
{
"login": "qcoudeyr",
"name": "qcoudeyr",
"avatar_url": "https://avatars.githubusercontent.com/u/124463277?v=4",
"profile": "https://github.com/qcoudeyr",
"contributions": [
"code"
]
}
],
"contributorsPerLine": 7,

View file

@ -11,20 +11,19 @@ jobs:
create-tag:
runs-on: ubuntu-latest
outputs:
tagname: ${{ steps.get_tag.outputs.tagname }}
tagname: ${{ steps.create_tag.outputs.tagname }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Get tag from package.json
id: get_tag
run: |
VERSION=$(npm run version --silent)
echo "tagname=v${VERSION}-alpha.${{ github.event.inputs.tag }}" >> $GITHUB_OUTPUT
- uses: rickstaa/action-create-tag@v1
- name: Create Tag
id: create_tag
uses: Klemensas/action-autotag@stable
with:
tag: ${{ steps.get_tag.outputs.tagname }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
tag_prefix: 'v'
tag_suffix: '-alpha.${{ github.event.inputs.tag }}'
build-worker:
runs-on: ubuntu-latest
@ -97,7 +96,7 @@ jobs:
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 18
- uses: pnpm/action-setup@v2.4.0
name: Install pnpm
@ -145,21 +144,25 @@ jobs:
name: cli
path: cli
- name: Rename CLI
run: |
mv cli/bin/cli-x64 ./runtipi-cli-linux-x64
- name: Create alpha release
id: create_release
uses: softprops/action-gh-release@v1
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
body: |
**${{ needs.create-tag.outputs.tagname }}**
tag_name: ${{ needs.create-tag.outputs.tagname }}
name: ${{ needs.create-tag.outputs.tagname }}
release_name: ${{ needs.create-tag.outputs.tagname }}
draft: false
prerelease: true
files: |
runtipi-cli-linux-x64
- name: Upload X64 Linux CLI binary to release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: cli/bin/cli-x64
asset_name: runtipi-cli-linux-x64
asset_content_type: application/octet-stream

View file

@ -11,20 +11,18 @@ jobs:
create-tag:
runs-on: ubuntu-latest
outputs:
tagname: ${{ steps.get_tag.outputs.tagname }}
tagname: ${{ steps.create_tag.outputs.tagname }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Get tag from package.json
id: get_tag
run: |
VERSION=$(npm run version --silent)
echo "tagname=v${VERSION}-beta.${{ github.event.inputs.tag }}" >> $GITHUB_OUTPUT
- uses: rickstaa/action-create-tag@v1
- name: Create Tag
id: create_tag
uses: Klemensas/action-autotag@stable
with:
tag: ${{ steps.get_tag.outputs.tagname }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
tag_prefix: 'v'
tag_suffix: '-beta.${{ github.event.inputs.tag }}'
build-worker:
runs-on: ubuntu-latest
@ -51,7 +49,7 @@ jobs:
with:
context: .
file: ./packages/worker/Dockerfile
platforms: linux/amd64,linux/arm64
platforms: linux/amd64
push: true
tags: ghcr.io/${{ github.repository_owner }}/worker:${{ needs.create-tag.outputs.tagname }}
cache-from: type=registry,ref=ghcr.io/${{ github.repository_owner }}/worker:buildcache
@ -81,7 +79,7 @@ jobs:
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
platforms: linux/amd64
push: true
tags: ghcr.io/${{ github.repository_owner }}/runtipi:${{ needs.create-tag.outputs.tagname }}
cache-from: type=registry,ref=ghcr.io/${{ github.repository_owner }}/runtipi:buildcache
@ -97,7 +95,7 @@ jobs:
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 18
- uses: pnpm/action-setup@v2.4.0
name: Install pnpm
@ -146,26 +144,38 @@ jobs:
name: cli
path: cli
- name: Rename CLI
run: |
mv cli/bin/cli-x64 ./runtipi-cli-linux-x64
mv cli/bin/cli-arm64 ./runtipi-cli-linux-arm64
- name: Create beta release
id: create_release
uses: softprops/action-gh-release@v1
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
body: |
**${{ needs.create-tag.outputs.tagname }}**
tag_name: ${{ needs.create-tag.outputs.tagname }}
name: ${{ needs.create-tag.outputs.tagname }}
release_name: ${{ needs.create-tag.outputs.tagname }}
draft: false
prerelease: true
files: |
runtipi-cli-linux-x64
runtipi-cli-linux-arm64
- name: Upload X64 Linux CLI binary to release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: cli/bin/cli-x64
asset_name: runtipi-cli-linux-x64
asset_content_type: application/octet-stream
- name: Upload ARM64 Linux CLI binary to release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: cli/bin/cli-arm64
asset_name: runtipi-cli-linux-arm64
asset_content_type: application/octet-stream
e2e-tests:
needs: [create-tag, publish-release]

View file

@ -43,7 +43,7 @@ jobs:
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 18
- uses: pnpm/action-setup@v2.4.0
name: Install pnpm
@ -106,7 +106,7 @@ jobs:
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 18
- uses: pnpm/action-setup@v2.4.0
name: Install pnpm

View file

@ -72,6 +72,9 @@ jobs:
run: |
while ! ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa root@${{ steps.get-droplet-ip.outputs.droplet_ip }} "echo 'SSH is ready'"; do sleep 5; done
- name: Wait 1 minute for Droplet to be ready
run: sleep 60
- name: Create docker group on Droplet
uses: fifsky/ssh-action@master
with:
@ -82,9 +85,6 @@ jobs:
user: root
key: ${{ secrets.SSH_KEY }}
- name: Wait 90 seconds for Docker to be ready on Droplet
run: sleep 90
- name: Deploy app to Droplet
uses: fifsky/ssh-action@master
with:
@ -134,7 +134,7 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: 20
node-version: 18
- name: Create .env.e2e file with Droplet IP
run: |

View file

@ -3,28 +3,28 @@ on:
workflow_dispatch:
jobs:
create-tag:
get-tag:
runs-on: ubuntu-latest
needs: [build-images, build-cli]
outputs:
tagname: ${{ steps.get_tag.outputs.tagname }}
tag: ${{ steps.get_tag.outputs.tag }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Get tag from package.json
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 18
- name: Get tag from VERSION file
id: get_tag
run: |
VERSION=$(npm run version --silent)
echo "tagname=v${VERSION}" >> $GITHUB_OUTPUT
- uses: rickstaa/action-create-tag@v1
with:
tag: ${{ steps.get_tag.outputs.tagname }}
echo "tag=v${VERSION}" >> $GITHUB_OUTPUT
build-images:
if: github.repository == 'runtipi/runtipi'
needs: create-tag
needs: get-tag
runs-on: ubuntu-latest
steps:
- name: Checkout
@ -49,45 +49,14 @@ jobs:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ghcr.io/${{ github.repository_owner }}/runtipi:${{ needs.create-tag.outputs.tagname }},ghcr.io/${{ github.repository_owner }}/runtipi:latest
tags: ghcr.io/${{ github.repository_owner }}/runtipi:${{ needs.get-tag.outputs.tag }},ghcr.io/${{ github.repository_owner }}/runtipi:latest
cache-from: type=registry,ref=ghcr.io/${{ github.repository_owner }}/runtipi:buildcache
cache-to: type=registry,ref=ghcr.io/${{ github.repository_owner }}/runtipi:buildcache,mode=max
build-worker:
runs-on: ubuntu-latest
needs: create-tag
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push images
uses: docker/build-push-action@v5
with:
context: .
file: ./packages/worker/Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: ghcr.io/${{ github.repository_owner }}/worker:${{ needs.create-tag.outputs.tagname }},ghcr.io/${{ github.repository_owner }}/worker:latest
cache-from: type=registry,ref=ghcr.io/${{ github.repository_owner }}/worker:buildcache
cache-to: type=registry,ref=ghcr.io/${{ github.repository_owner }}/worker:buildcache,mode=max
build-cli:
runs-on: ubuntu-latest
timeout-minutes: 10
needs: create-tag
needs: get-tag
steps:
- name: Checkout code
uses: actions/checkout@v4
@ -95,7 +64,7 @@ jobs:
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 18
- uses: pnpm/action-setup@v2.4.0
name: Install pnpm
@ -121,7 +90,7 @@ jobs:
run: pnpm install
- name: Set version
run: pnpm -r --filter cli set-version ${{ needs.create-tag.outputs.tagname }}
run: pnpm -r --filter cli set-version ${{ needs.get-tag.outputs.tag }}
- name: Build CLI
run: pnpm -r --filter cli package
@ -132,9 +101,25 @@ jobs:
name: cli
path: packages/cli/dist
create-tag:
runs-on: ubuntu-latest
needs: [build-images, build-cli]
outputs:
tagname: ${{ steps.create_tag.outputs.tagname }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Create Tag
id: create_tag
uses: Klemensas/action-autotag@stable
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
tag_prefix: 'v'
publish-release:
runs-on: ubuntu-latest
needs: [create-tag, build-images, build-worker, build-cli]
needs: [create-tag]
outputs:
id: ${{ steps.create_release.outputs.id }}
steps:
@ -144,26 +129,38 @@ jobs:
name: cli
path: cli
- name: Rename CLI
run: |
mv cli/bin/cli-x64 ./runtipi-cli-linux-x64
mv cli/bin/cli-arm64 ./runtipi-cli-linux-arm64
- name: Create release
id: create_release
uses: softprops/action-gh-release@v1
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
body: |
**${{ needs.create-tag.outputs.tagname }}**
tag_name: ${{ needs.create-tag.outputs.tagname }}
name: ${{ needs.create-tag.outputs.tagname }}
release_name: ${{ needs.create-tag.outputs.tagname }}
draft: false
prerelease: true
files: |
runtipi-cli-linux-x64
runtipi-cli-linux-arm64
- name: Upload X64 Linux CLI binary to release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: cli/bin/cli-x64
asset_name: runtipi-cli-linux-x64
asset_content_type: application/octet-stream
- name: Upload ARM64 Linux CLI binary to release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: cli/bin/cli-arm64
asset_name: runtipi-cli-linux-arm64
asset_content_type: application/octet-stream
e2e-tests:
needs: [create-tag, publish-release]

View file

@ -1,4 +1,4 @@
ARG NODE_VERSION="20.10"
ARG NODE_VERSION="18.16"
ARG ALPINE_VERSION="3.18"
FROM node:${NODE_VERSION}-alpine${ALPINE_VERSION} AS node_base

View file

@ -1,4 +1,4 @@
ARG NODE_VERSION="20.10"
ARG NODE_VERSION="18.16"
ARG ALPINE_VERSION="3.18"
FROM node:${NODE_VERSION}-alpine${ALPINE_VERSION}

View file

@ -1,7 +1,7 @@
# Tipi — A personal homeserver for everyone
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-42-orange.svg?style=flat-square)](#contributors-)
[![All Contributors](https://img.shields.io/badge/all_contributors-40-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->
[![License](https://img.shields.io/github/license/runtipi/runtipi)](https://github.com/runtipi/runtipi/blob/master/LICENSE)
@ -123,8 +123,6 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<td align="center" valign="top" width="14.28%"><a href="https://github.com/itsrllyhim"><img src="https://avatars.githubusercontent.com/u/143047010?v=4?s=100" width="100px;" alt="him"/><br /><sub><b>him</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=itsrllyhim" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://cchalop1.com"><img src="https://avatars.githubusercontent.com/u/28163855?v=4?s=100" width="100px;" alt="CHALOPIN Clément"/><br /><sub><b>CHALOPIN Clément</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=cchalop1" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/geetansh"><img src="https://avatars.githubusercontent.com/u/9976198?v=4?s=100" width="100px;" alt="Geetansh Jindal"/><br /><sub><b>Geetansh Jindal</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=geetansh" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/0livier"><img src="https://avatars.githubusercontent.com/u/10607?v=4?s=100" width="100px;" alt="Olivier Garcia"/><br /><sub><b>Olivier Garcia</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=0livier" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/qcoudeyr"><img src="https://avatars.githubusercontent.com/u/124463277?v=4?s=100" width="100px;" alt="qcoudeyr"/><br /><sub><b>qcoudeyr</b></sub></a><br /><a href="https://github.com/runtipi/runtipi/commits?author=qcoudeyr" title="Code">💻</a></td>
</tr>
</tbody>
</table>

View file

@ -60,6 +60,7 @@ services:
context: .
dockerfile: ./packages/worker/Dockerfile.dev
container_name: tipi-worker
user: root
healthcheck:
test: ['CMD', 'curl', '-f', 'http://localhost:3000/healthcheck']
interval: 5s

View file

@ -1,6 +1,6 @@
{
"name": "runtipi",
"version": "2.2.1",
"version": "2.2.0",
"description": "A homeserver for everyone",
"scripts": {
"knip": "knip",
@ -45,14 +45,13 @@
"@runtipi/postgres-migrations": "^5.3.0",
"@runtipi/shared": "workspace:^",
"@tabler/core": "1.0.0-beta20",
"@tabler/icons-react": "^2.42.0",
"@tabler/icons-react": "^2.40.0",
"argon2": "^0.31.2",
"bullmq": "^4.13.0",
"clsx": "^2.0.0",
"connect-redis": "^7.1.0",
"drizzle-orm": "^0.28.6",
"fs-extra": "^11.1.1",
"geist": "^1.2.0",
"let-it-go": "^1.0.0",
"lodash.merge": "^4.6.2",
"next": "14.0.1",
@ -67,7 +66,7 @@
"react-hot-toast": "^2.4.1",
"react-markdown": "^9.0.0",
"react-select": "^5.8.0",
"react-tooltip": "^5.25.0",
"react-tooltip": "^5.22.0",
"redaxios": "^0.5.1",
"redis": "^4.6.10",
"rehype-raw": "^7.0.0",
@ -95,16 +94,16 @@
"@total-typescript/shoehorn": "^0.1.1",
"@total-typescript/ts-reset": "^0.5.1",
"@types/fs-extra": "^11.0.4",
"@types/jest": "^29.5.11",
"@types/jest": "^29.5.7",
"@types/lodash.merge": "^4.6.8",
"@types/node": "20.8.10",
"@types/pg": "^8.10.7",
"@types/react": "18.2.39",
"@types/react": "18.2.34",
"@types/react-dom": "18.2.14",
"@types/semver": "^7.5.4",
"@types/uuid": "^9.0.6",
"@types/validator": "^13.11.5",
"@typescript-eslint/eslint-plugin": "^6.13.1",
"@typescript-eslint/eslint-plugin": "^6.9.1",
"@typescript-eslint/parser": "^6.10.0",
"@vitejs/plugin-react": "^4.1.1",
"@vitest/coverage-v8": "^0.34.6",
@ -112,7 +111,7 @@
"eslint": "8.52.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-airbnb-typescript": "^17.1.0",
"eslint-config-next": "14.0.3",
"eslint-config-next": "14.0.1",
"eslint-config-prettier": "^9.0.0",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.29.0",

View file

@ -21,7 +21,7 @@ services:
tipi-db:
container_name: tipi-db
image: postgres:14
restart: unless-stopped
restart: on-failure
stop_grace_period: 1m
ports:
- ${POSTGRES_PORT:-5432}:5432
@ -60,6 +60,7 @@ services:
container_name: tipi-worker
image: ghcr.io/runtipi/worker:${TIPI_VERSION}
restart: unless-stopped
user: root
healthcheck:
test: ['CMD', 'curl', '-f', 'http://localhost:3000/healthcheck']
interval: 5s

View file

@ -8,7 +8,7 @@ async function bundle() {
entryPoints: ['./src/index.ts'],
outfile: './dist/index.js',
platform: 'node',
target: 'node20',
target: 'node18',
bundle: true,
color: true,
sourcemap: commandArgs.includes('--sourcemap'),

View file

@ -8,10 +8,10 @@
"test": "dotenv -e .env.test vitest -- --coverage --watch=false --passWithNoTests",
"test:watch": "dotenv -e .env.test vitest",
"package": "npm run build && pkg package.json && chmod +x dist/bin/cli-x64 && chmod +x dist/bin/cli-arm64",
"package:m1": "npm run build && pkg package.json -t node20-darwin-arm64",
"package:m1": "npm run build && pkg package.json -t node18-darwin-arm64",
"set-version": "node -e \"require('fs').writeFileSync('assets/VERSION', process.argv[1])\"",
"build": "node build.js",
"build:meta": "esbuild ./src/index.ts --bundle --platform=node --target=node20 --outfile=dist/index.js --metafile=meta.json --analyze",
"build:meta": "esbuild ./src/index.ts --bundle --platform=node --target=node18 --outfile=dist/index.js --metafile=meta.json --analyze",
"dev": "dotenv -e ../../.env nodemon",
"lint": "eslint . --ext .ts",
"tsc": "tsc --noEmit",
@ -20,8 +20,8 @@
"pkg": {
"assets": "assets/**/*",
"targets": [
"node20-linux-x64",
"node20-linux-arm64"
"node18-linux-x64",
"node18-linux-arm64"
],
"outputPath": "dist/bin"
},
@ -30,7 +30,7 @@
"license": "ISC",
"devDependencies": {
"@faker-js/faker": "^8.2.0",
"@types/cli-progress": "^3.11.5",
"@types/cli-progress": "^3.11.4",
"@types/node": "20.8.10",
"dotenv-cli": "^7.3.0",
"esbuild": "^0.19.4",

View file

@ -1,4 +1,4 @@
ARG NODE_VERSION="20.10"
ARG NODE_VERSION="18.16"
ARG ALPINE_VERSION="3.18"
FROM node:${NODE_VERSION}-alpine${ALPINE_VERSION} AS node_base

View file

@ -1,4 +1,4 @@
ARG NODE_VERSION="20.10"
ARG NODE_VERSION="18.16"
ARG ALPINE_VERSION="3.18"
FROM node:${NODE_VERSION}-alpine${ALPINE_VERSION} AS node_base

View file

@ -8,7 +8,7 @@ async function bundle() {
entryPoints: ['./src/index.ts'],
outfile: './dist/index.js',
platform: 'node',
target: 'node20',
target: 'node18',
bundle: true,
color: true,
sourcemap: commandArgs.includes('--sourcemap'),

View file

@ -4,7 +4,7 @@ import path from 'node:path';
import Redis from 'ioredis';
import dotenv from 'dotenv';
import { Queue } from 'bullmq';
import { copySystemFiles, ensureFilePermissions, generateSystemEnvFile, generateTlsCertificates } from '@/lib/system';
import { copySystemFiles, generateSystemEnvFile, generateTlsCertificates } from '@/lib/system';
import { runPostgresMigrations } from '@/lib/migrations';
import { startWorker } from './watcher/watcher';
import { logger } from '@/lib/logger';
@ -30,9 +30,6 @@ const main = async () => {
logger.info('Generating TLS certificates...');
await generateTlsCertificates({ domain: envMap.get('LOCAL_DOMAIN') });
logger.info('Ensuring file permissions...');
await ensureFilePermissions();
logger.info('Starting queue...');
const queue = new Queue('events', { connection: { host: envMap.get('REDIS_HOST'), port: 6379, password: envMap.get('REDIS_PASSWORD') } });
logger.info('Obliterating queue...');

View file

@ -259,7 +259,16 @@ export const generateTlsCertificates = async (data: { domain?: string }) => {
};
export const ensureFilePermissions = async () => {
const filesAndFolders = [path.join(ROOT_FOLDER, 'state'), path.join(ROOT_FOLDER, 'traefik')];
const filesAndFolders = [
path.join(ROOT_FOLDER, 'apps'),
path.join(ROOT_FOLDER, 'logs'),
path.join(ROOT_FOLDER, 'repos'),
path.join(ROOT_FOLDER, 'state'),
path.join(ROOT_FOLDER, 'traefik'),
path.join(ROOT_FOLDER, '.env'),
path.join(ROOT_FOLDER, 'VERSION'),
path.join(ROOT_FOLDER, 'docker-compose.yml'),
];
const files600 = [path.join(ROOT_FOLDER, 'traefik', 'shared', 'acme.json')];

View file

@ -1,6 +1,6 @@
import path from 'path';
import { execAsync, pathExists } from '@runtipi/shared';
import { getRepoHash, getRepoBaseUrlAndBranch } from './repo.helpers';
import { getRepoHash } from './repo.helpers';
import { logger } from '@/lib/logger';
export class RepoExecutors {
@ -26,32 +26,21 @@ export class RepoExecutors {
/**
* Given a repo url, clone it to the repos folder if it doesn't exist
*
* @param {string} url
* @param {string} repoUrl
*/
public cloneRepo = async (url: string) => {
public cloneRepo = async (repoUrl: string) => {
try {
// We may have a potential branch computed in the hash (see getRepoBaseUrlAndBranch)
// so we do it here before splitting the url into repoUrl and branch
const repoHash = getRepoHash(url);
const repoHash = getRepoHash(repoUrl);
const repoPath = path.join('/app', 'repos', repoHash);
if (await pathExists(repoPath)) {
this.logger.info(`Repo ${url} already exists`);
this.logger.info(`Repo ${repoUrl} already exists`);
return { success: true, message: '' };
}
const [repoUrl, branch] = getRepoBaseUrlAndBranch(url);
this.logger.info(`Cloning repo ${repoUrl} to ${repoPath}`);
let cloneCommand;
if (branch) {
this.logger.info(`Cloning repo ${repoUrl} on branch ${branch} to ${repoPath}`);
cloneCommand = `git clone -b ${branch} ${repoUrl} ${repoPath}`;
} else {
this.logger.info(`Cloning repo ${repoUrl} to ${repoPath}`);
cloneCommand = `git clone ${repoUrl} ${repoPath}`;
}
await execAsync(cloneCommand);
await execAsync(`git clone ${repoUrl} ${repoPath}`);
this.logger.info(`Cloned repo ${repoUrl} to ${repoPath}`);
return { success: true, message: '' };

View file

@ -10,18 +10,3 @@ export const getRepoHash = (repoUrl: string) => {
hash.update(repoUrl);
return hash.digest('hex');
};
/**
* Extracts the base URL and branch from a repository URL.
* @param repoUrl The repository URL.
* @returns An array containing the base URL and branch, or just the base URL if no branch is found.
*/
export const getRepoBaseUrlAndBranch = (repoUrl: string) => {
const branchMatch = repoUrl.match(/^(.*)\/tree\/(.*)$/);
if (branchMatch) {
return [branchMatch[1], branchMatch[2]] ;
}
return [repoUrl, undefined] ;
};

2530
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

View file

@ -121,12 +121,16 @@ if ! command -v docker >/dev/null; then
install_docker "${OS}"
docker_result=$?
if [[ docker_result -ne 0 ]]; then
if [[ docker_result -eq 0 ]]; then
echo "Docker installed"
else
echo "Your system ${OS} is not supported trying with sub_os ${SUB_OS}"
install_docker "${SUB_OS}"
docker_sub_result=$?
if [[ docker_sub_result -ne 0 ]]; then
if [[ docker_sub_result -eq 0 ]]; then
echo "Docker installed"
else
echo "Your system ${SUB_OS} is not supported please install docker manually"
exit 1
fi
@ -134,15 +138,11 @@ if ! command -v docker >/dev/null; then
# Make sure user is in docker group
if ! groups | grep -q '\bdocker\b'; then
echo "Adding user to docker group"
sudo usermod -aG docker "$USER"
echo "✓ Docker installed. Please re-run the installation script to continue with the installation. (curl -L https://setup.runtipi.io | bash)"
fi
# Reload user groups
newgrp docker
exit 0
fi
function check_dependency_and_install() {

View file

@ -94,11 +94,11 @@ export const AppDetailsContainer: React.FC<IProps> = ({ app, localDomain }) => {
const updateMutation = useAction(updateAppAction, {
onSuccess: (data) => {
setCustomStatus(app.status);
if (!data.success) {
setCustomStatus(app.status);
toast.error(data.failure.reason);
} else {
setCustomStatus('stopped');
toast.success(t('apps.app-details.update-success'));
}
},

View file

@ -2,7 +2,7 @@ import React from 'react';
import type { Metadata } from 'next';
import { cookies } from 'next/headers';
import { GeistSans } from 'geist/font/sans';
import { Inter } from 'next/font/google';
import merge from 'lodash.merge';
import { NextIntlClientProvider } from 'next-intl';
import { getConfig } from '@/server/core/TipiConfig';
@ -13,6 +13,11 @@ import { Toaster } from 'react-hot-toast';
import { getCurrentLocale } from '../utils/getCurrentLocale';
import { ClientProviders } from './components/ClientProviders';
const inter = Inter({
subsets: ['latin'],
display: 'swap',
});
export const metadata: Metadata = {
title: 'Tipi',
description: 'Tipi',
@ -30,7 +35,7 @@ export default async function RootLayout({ children }: { children: React.ReactNo
const { allowAutoThemes } = getConfig();
return (
<html lang={locale} className={clsx(GeistSans.className, 'border-top-wide border-primary')}>
<html lang={locale} className={clsx(inter.className, 'border-top-wide border-primary')}>
<NextIntlClientProvider locale={locale} messages={mergedMessages}>
<ClientProviders initialTheme={theme?.value} cookies={cookies().getAll()} allowAutoThemes={allowAutoThemes}>
<body data-bs-theme={theme?.value}>

View file

@ -477,7 +477,7 @@ describe('Update app', () => {
it('Should correctly update app', async () => {
// arrange
const appConfig = createAppConfig({});
await insertApp({ version: 12, status: 'running', config: { TEST_FIELD: 'test' } }, appConfig, db);
await insertApp({ version: 12, config: { TEST_FIELD: 'test' } }, appConfig, db);
// act
await updateApp(appConfig.id, { version: 0 }, db);
@ -487,7 +487,7 @@ describe('Update app', () => {
expect(app).toBeDefined();
expect(app?.config).toStrictEqual({ TEST_FIELD: 'test' });
expect(app?.version).toBe(appConfig.tipi_version);
expect(app?.status).toBe('running');
expect(app?.status).toBe('stopped');
});
it("Should throw if app doesn't exist", async () => {
@ -505,16 +505,6 @@ describe('Update app', () => {
const app = await getAppById(appConfig.id, db);
expect(app?.status).toBe('stopped');
});
it('Should comme back to the previous status before the update of the app', async () => {
// arrange
const appConfig = createAppConfig({});
await insertApp({ status: 'stopped' }, appConfig, db);
// act & assert
await updateApp(appConfig.id, { version: 0 }, db);
const app = await getAppById(appConfig.id, db);
expect(app?.status).toBe('stopped');
});
});
describe('installedApps', () => {

View file

@ -341,7 +341,6 @@ export class AppServiceClass {
*/
public updateApp = async (id: string) => {
const app = await this.queries.getApp(id);
const appStatusBeforeUpdate = app?.status;
if (!app) {
throw new TranslatedError('server-messages.errors.app-not-found', { id });
@ -356,19 +355,14 @@ export class AppServiceClass {
if (success) {
const appInfo = getAppInfo(app.id, app.status);
await this.queries.updateApp(id, { version: appInfo?.tipi_version });
if (appStatusBeforeUpdate === 'running') {
await this.startApp(id);
} else {
await this.queries.updateApp(id, { status: appStatusBeforeUpdate });
}
await this.queries.updateApp(id, { status: 'running', version: appInfo?.tipi_version });
} else {
await this.queries.updateApp(id, { status: 'stopped' });
Logger.error(`Failed to update app ${id}: ${stdout}`);
throw new TranslatedError('server-messages.errors.app-failed-to-update', { id });
}
const updatedApp = await this.getApp(id);
const updatedApp = await this.queries.updateApp(id, { status: 'stopped' });
return updatedApp;
};