Compare commits

...

59 commits

Author SHA1 Message Date
allcontributors[bot]
c962f030e3 docs: update .all-contributorsrc [skip ci] 2023-12-07 08:15:30 +01:00
allcontributors[bot]
1f5701120f docs: update README.md [skip ci] 2023-12-07 08:15:30 +01:00
dependabot[bot]
249103f0a6 chore(deps-dev): bump @types/jest from 29.5.7 to 29.5.11
Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 29.5.7 to 29.5.11.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest)

---
updated-dependencies:
- dependency-name: "@types/jest"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-06 21:04:50 +01:00
dependabot[bot]
bb1f343ac9 chore(deps): bump react-tooltip from 5.22.0 to 5.25.0
Bumps [react-tooltip](https://github.com/ReactTooltip/react-tooltip) from 5.22.0 to 5.25.0.
- [Release notes](https://github.com/ReactTooltip/react-tooltip/releases)
- [Changelog](https://github.com/ReactTooltip/react-tooltip/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ReactTooltip/react-tooltip/compare/v5.22.0...v5.25.0)

---
updated-dependencies:
- dependency-name: react-tooltip
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-06 20:50:02 +01:00
Stavros
6b371de137 refactor(ui): change font to geist 2023-12-06 20:44:51 +01:00
Nicolas Meienberger
7133a2a2dc Merge branch 'master' into develop 2023-12-01 09:12:31 +01:00
Nicolas Meienberger
44d40b4a34 Merge branch 'hotfix/restart-failure' 2023-12-01 09:07:26 +01:00
Nicolas Meienberger
03e2604ca0 hotfix(docker): make postgres restart policy "unless-stopped" instead of "on-failure" 2023-12-01 08:44:53 +01:00
Nicolas Meienberger
ba3d860176 hotfix(install.sh): ask to re-run install script after docker is installed 2023-11-29 18:34:50 +01:00
Nicolas Meienberger
250e78450f chore: bump node to 20 in dockerfiles and actions 2023-11-29 08:41:35 +01:00
dependabot[bot]
d11299eeb8 chore(deps-dev): bump @types/cli-progress from 3.11.4 to 3.11.5
Bumps [@types/cli-progress](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/cli-progress) from 3.11.4 to 3.11.5.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/cli-progress)

---
updated-dependencies:
- dependency-name: "@types/cli-progress"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-29 08:22:40 +01:00
dependabot[bot]
6cd7ca1a4e chore(deps): bump @tabler/icons-react from 2.40.0 to 2.42.0
Bumps [@tabler/icons-react](https://github.com/tabler/tabler-icons/tree/HEAD/packages/icons-react) from 2.40.0 to 2.42.0.
- [Release notes](https://github.com/tabler/tabler-icons/releases)
- [Commits](https://github.com/tabler/tabler-icons/commits/v2.42.0/packages/icons-react)

---
updated-dependencies:
- dependency-name: "@tabler/icons-react"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-29 08:22:22 +01:00
dependabot[bot]
bb9f26b2b1 chore(deps-dev): bump @types/react from 18.2.34 to 18.2.39
Bumps [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) from 18.2.34 to 18.2.39.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

---
updated-dependencies:
- dependency-name: "@types/react"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-29 08:22:09 +01:00
dependabot[bot]
30890bedd5 chore(deps-dev): bump eslint-config-next from 14.0.1 to 14.0.3
Bumps [eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next) from 14.0.1 to 14.0.3.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/commits/v14.0.3/packages/eslint-config-next)

---
updated-dependencies:
- dependency-name: eslint-config-next
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-29 08:21:58 +01:00
dependabot[bot]
3876e8ee55 chore(deps-dev): bump @typescript-eslint/eslint-plugin
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.9.1 to 6.13.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.13.1/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-29 08:21:44 +01:00
Nicolas Meienberger
92d5a7b6a3 ci(release): make publish dependant on all builds 2023-11-28 22:31:44 +01:00
Nicolas Meienberger
ca3dc64fd4 ci(release): fix dependency on first job 2023-11-28 22:30:30 +01:00
Nicolas Meienberger
59dbe672c8
Merge pull request #960 from runtipi/release/2.2.0
Release 2.2.0
2023-11-28 22:29:01 +01:00
Nicolas Meienberger
42349c5a27 fix(worker): no need to mount host 2023-11-28 22:02:52 +01:00
Nicolas Meienberger
8104a9f3f7 ci(e2e): update upgrade before running install script 2023-11-28 19:12:40 +01:00
Nicolas Meienberger
83e96cfd31 ci(releases): refactor to use non-outdated actions 2023-11-28 19:12:35 +01:00
Nicolas Meienberger
4d69fc4cff ci(e2e): update upgrade before running install script 2023-11-28 18:49:47 +01:00
Nicolas Meienberger
37c551da1f ci(releases): refactor to use non-outdated actions 2023-11-28 13:29:02 +01:00
Nicolas Meienberger
852128f551 fix(worker): default to disk 0 if /host/root not found
In order to avoid displaying 0 disk space on some systems, we default to the first disk found
2023-11-28 08:26:43 +01:00
Nicolas Meienberger
bffa31c0b7 fix(worker): default to disk 0 if /host/root not found
In order to avoid displaying 0 disk space on some systems, we default to the first disk found
2023-11-28 08:18:48 +01:00
Nicolas Meienberger
0f129a7809 Merge branch 'steveiliop56-develop' into develop 2023-11-27 21:07:51 +01:00
Nicolas Meienberger
79b448adf3 fix(worker): apply file permissions on start 2023-11-27 21:06:14 +01:00
Nicolas Meienberger
dffa3ed670 ci(beta): build arm64 images 2023-11-27 21:06:14 +01:00
allcontributors[bot]
ef1ac3633b docs: update .all-contributorsrc [skip ci] 2023-11-27 21:06:14 +01:00
allcontributors[bot]
e520afdeff docs: update README.md [skip ci] 2023-11-27 21:06:14 +01:00
Olivier Garcia
52499cb0bd feat(support-repoURL-with-branch-syntax): If a appstore repo URL contains a branch, checkout that branch 2023-11-27 21:06:14 +01:00
Nicolas Meienberger
cfeb9d4e19 fix(app-status): rely on server status after update 2023-11-27 21:06:14 +01:00
Nicolas Meienberger
a1515ac7b8 ci(beta): adapt workflow with new worker build 2023-11-27 21:06:14 +01:00
Nicolas Meienberger
396d08dde0 feat(ThemeProvider): add some magic 2023-11-27 21:06:14 +01:00
Nicolas Meienberger
3c7dcfeb5e ci(release): replace butlerlogic/action-autotag with Klemensas/action-autotag 2023-11-27 21:06:14 +01:00
dependabot[bot]
9b5bcc7147 chore(deps-dev): bump @types/web-push from 3.6.2 to 3.6.3
Bumps [@types/web-push](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/web-push) from 3.6.2 to 3.6.3.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/web-push)

---
updated-dependencies:
- dependency-name: "@types/web-push"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-27 21:05:46 +01:00
cchalopin
5c276bd235 feat(update app): fix tests 2023-11-27 21:05:34 +01:00
cchalopin
c1723bb36b feat(update app): change pnpm 2023-11-27 21:05:34 +01:00
cchalopin
31c3de78b8 feat(update app): back to prev status before update 2023-11-27 21:05:12 +01:00
Nicolas Meienberger
197f6e3998 fix(worker): ensure state folder is rwx for non-root users 2023-11-27 21:04:48 +01:00
Nicolas Meienberger
abff9a4d5a fix(worker): apply file permissions on start 2023-11-27 09:41:42 +01:00
Nicolas Meienberger
91a361add1 ci(beta): build arm64 images 2023-11-27 09:41:37 +01:00
allcontributors[bot]
68b3e4e8bd docs: update .all-contributorsrc [skip ci] 2023-11-27 08:21:57 +01:00
allcontributors[bot]
f893cf482d docs: update README.md [skip ci] 2023-11-27 08:21:57 +01:00
Olivier Garcia
88878fccda feat(support-repoURL-with-branch-syntax): If a appstore repo URL contains a branch, checkout that branch 2023-11-27 08:19:22 +01:00
Nicolas Meienberger
64325150d5 fix(app-status): rely on server status after update 2023-11-27 08:10:29 +01:00
Nicolas Meienberger
203db0160a Merge branch 'cchalop1-feat/restart-app-after-update' into develop 2023-11-27 07:42:43 +01:00
Nicolas Meienberger
0261cf577c fix(worker): ensure state folder is rwx for non-root users 2023-11-27 07:42:36 +01:00
Nicolas Meienberger
166d9b49f2 ci(beta): adapt workflow with new worker build 2023-11-27 07:42:36 +01:00
Nicolas Meienberger
213b9ed482 feat(ThemeProvider): add some magic 2023-11-27 07:42:36 +01:00
Nicolas Meienberger
de3141e1f8 ci(release): replace butlerlogic/action-autotag with Klemensas/action-autotag 2023-11-27 07:42:36 +01:00
dependabot[bot]
6ec79ac1e8 chore(deps-dev): bump @types/web-push from 3.6.2 to 3.6.3
Bumps [@types/web-push](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/web-push) from 3.6.2 to 3.6.3.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/web-push)

---
updated-dependencies:
- dependency-name: "@types/web-push"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-27 07:42:36 +01:00
Nicolas Meienberger
5dbc996b92 refactor(docker): use non-root user in dashboard image 2023-11-27 07:42:36 +01:00
Nicolas Meienberger
f76af65212 fix(worker): ensure state folder is rwx for non-root users 2023-11-27 07:42:16 +01:00
cchalopin
1357efa0e3 feat(update app): fix tests 2023-11-26 15:17:27 +01:00
cchalopin
4da6193ae9 feat(update app): change pnpm 2023-11-26 15:12:09 +01:00
cchalopin
f61e6b2dae feat(update app): back to prev status before update 2023-11-26 15:03:21 +01:00
Stavros
230ae0a412 fix(worker): remount / to /host/root 2023-11-26 11:17:11 +02:00
Nicolas Meienberger
df59d21ce7
Merge pull request #879 from runtipi/release/2.1.0
Release 2.1.0
2023-11-07 22:14:38 +01:00
27 changed files with 501 additions and 2411 deletions

View file

@ -382,6 +382,24 @@
"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,19 +11,20 @@ jobs:
create-tag:
runs-on: ubuntu-latest
outputs:
tagname: ${{ steps.create_tag.outputs.tagname }}
tagname: ${{ steps.get_tag.outputs.tagname }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Create Tag
id: create_tag
uses: Klemensas/action-autotag@stable
- 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
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
tag_prefix: 'v'
tag_suffix: '-alpha.${{ github.event.inputs.tag }}'
tag: ${{ steps.get_tag.outputs.tagname }}
build-worker:
runs-on: ubuntu-latest
@ -96,7 +97,7 @@ jobs:
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20
- uses: pnpm/action-setup@v2.4.0
name: Install pnpm
@ -144,25 +145,21 @@ 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: actions/create-release@v1
uses: softprops/action-gh-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
body: |
**${{ needs.create-tag.outputs.tagname }}**
tag_name: ${{ needs.create-tag.outputs.tagname }}
release_name: ${{ needs.create-tag.outputs.tagname }}
name: ${{ needs.create-tag.outputs.tagname }}
draft: false
prerelease: true
- 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
files: |
runtipi-cli-linux-x64

View file

@ -11,18 +11,20 @@ jobs:
create-tag:
runs-on: ubuntu-latest
outputs:
tagname: ${{ steps.create_tag.outputs.tagname }}
tagname: ${{ steps.get_tag.outputs.tagname }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Create Tag
id: create_tag
uses: Klemensas/action-autotag@stable
- 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
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
tag_prefix: 'v'
tag_suffix: '-beta.${{ github.event.inputs.tag }}'
tag: ${{ steps.get_tag.outputs.tagname }}
build-worker:
runs-on: ubuntu-latest
@ -49,7 +51,7 @@ jobs:
with:
context: .
file: ./packages/worker/Dockerfile
platforms: linux/amd64
platforms: linux/amd64,linux/arm64
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
@ -79,7 +81,7 @@ jobs:
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64
platforms: linux/amd64,linux/arm64
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
@ -95,7 +97,7 @@ jobs:
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20
- uses: pnpm/action-setup@v2.4.0
name: Install pnpm
@ -144,38 +146,26 @@ 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: actions/create-release@v1
uses: softprops/action-gh-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
body: |
**${{ needs.create-tag.outputs.tagname }}**
tag_name: ${{ needs.create-tag.outputs.tagname }}
release_name: ${{ needs.create-tag.outputs.tagname }}
name: ${{ needs.create-tag.outputs.tagname }}
draft: false
prerelease: true
- 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
files: |
runtipi-cli-linux-x64
runtipi-cli-linux-arm64
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: 18
node-version: 20
- 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: 18
node-version: 20
- uses: pnpm/action-setup@v2.4.0
name: Install pnpm

View file

@ -72,9 +72,6 @@ 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:
@ -85,6 +82,9 @@ 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: 18
node-version: 20
- name: Create .env.e2e file with Droplet IP
run: |

View file

@ -3,28 +3,28 @@ on:
workflow_dispatch:
jobs:
get-tag:
create-tag:
runs-on: ubuntu-latest
needs: [build-images, build-cli]
outputs:
tag: ${{ steps.get_tag.outputs.tag }}
tagname: ${{ steps.get_tag.outputs.tagname }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 18
- name: Get tag from VERSION file
- name: Get tag from package.json
id: get_tag
run: |
VERSION=$(npm run version --silent)
echo "tag=v${VERSION}" >> $GITHUB_OUTPUT
echo "tagname=v${VERSION}" >> $GITHUB_OUTPUT
- uses: rickstaa/action-create-tag@v1
with:
tag: ${{ steps.get_tag.outputs.tagname }}
build-images:
if: github.repository == 'runtipi/runtipi'
needs: get-tag
needs: create-tag
runs-on: ubuntu-latest
steps:
- name: Checkout
@ -49,14 +49,45 @@ jobs:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ghcr.io/${{ github.repository_owner }}/runtipi:${{ needs.get-tag.outputs.tag }},ghcr.io/${{ github.repository_owner }}/runtipi:latest
tags: ghcr.io/${{ github.repository_owner }}/runtipi:${{ needs.create-tag.outputs.tagname }},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: get-tag
needs: create-tag
steps:
- name: Checkout code
uses: actions/checkout@v4
@ -64,7 +95,7 @@ jobs:
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20
- uses: pnpm/action-setup@v2.4.0
name: Install pnpm
@ -90,7 +121,7 @@ jobs:
run: pnpm install
- name: Set version
run: pnpm -r --filter cli set-version ${{ needs.get-tag.outputs.tag }}
run: pnpm -r --filter cli set-version ${{ needs.create-tag.outputs.tagname }}
- name: Build CLI
run: pnpm -r --filter cli package
@ -101,25 +132,9 @@ 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]
needs: [create-tag, build-images, build-worker, build-cli]
outputs:
id: ${{ steps.create_release.outputs.id }}
steps:
@ -129,38 +144,26 @@ 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: actions/create-release@v1
uses: softprops/action-gh-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
body: |
**${{ needs.create-tag.outputs.tagname }}**
tag_name: ${{ needs.create-tag.outputs.tagname }}
release_name: ${{ needs.create-tag.outputs.tagname }}
name: ${{ needs.create-tag.outputs.tagname }}
draft: false
prerelease: true
- 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
files: |
runtipi-cli-linux-x64
runtipi-cli-linux-arm64
e2e-tests:
needs: [create-tag, publish-release]

View file

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

View file

@ -1,4 +1,4 @@
ARG NODE_VERSION="18.16"
ARG NODE_VERSION="20.10"
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-40-orange.svg?style=flat-square)](#contributors-)
[![All Contributors](https://img.shields.io/badge/all_contributors-42-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,6 +123,8 @@ 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,7 +60,6 @@ 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.0",
"version": "2.2.1",
"description": "A homeserver for everyone",
"scripts": {
"knip": "knip",
@ -45,13 +45,14 @@
"@runtipi/postgres-migrations": "^5.3.0",
"@runtipi/shared": "workspace:^",
"@tabler/core": "1.0.0-beta20",
"@tabler/icons-react": "^2.40.0",
"@tabler/icons-react": "^2.42.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",
@ -66,7 +67,7 @@
"react-hot-toast": "^2.4.1",
"react-markdown": "^9.0.0",
"react-select": "^5.8.0",
"react-tooltip": "^5.22.0",
"react-tooltip": "^5.25.0",
"redaxios": "^0.5.1",
"redis": "^4.6.10",
"rehype-raw": "^7.0.0",
@ -94,16 +95,16 @@
"@total-typescript/shoehorn": "^0.1.1",
"@total-typescript/ts-reset": "^0.5.1",
"@types/fs-extra": "^11.0.4",
"@types/jest": "^29.5.7",
"@types/jest": "^29.5.11",
"@types/lodash.merge": "^4.6.8",
"@types/node": "20.8.10",
"@types/pg": "^8.10.7",
"@types/react": "18.2.34",
"@types/react": "18.2.39",
"@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.9.1",
"@typescript-eslint/eslint-plugin": "^6.13.1",
"@typescript-eslint/parser": "^6.10.0",
"@vitejs/plugin-react": "^4.1.1",
"@vitest/coverage-v8": "^0.34.6",
@ -111,7 +112,7 @@
"eslint": "8.52.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-airbnb-typescript": "^17.1.0",
"eslint-config-next": "14.0.1",
"eslint-config-next": "14.0.3",
"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: on-failure
restart: unless-stopped
stop_grace_period: 1m
ports:
- ${POSTGRES_PORT:-5432}:5432
@ -60,7 +60,6 @@ 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: 'node18',
target: 'node20',
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 node18-darwin-arm64",
"package:m1": "npm run build && pkg package.json -t node20-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=node18 --outfile=dist/index.js --metafile=meta.json --analyze",
"build:meta": "esbuild ./src/index.ts --bundle --platform=node --target=node20 --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": [
"node18-linux-x64",
"node18-linux-arm64"
"node20-linux-x64",
"node20-linux-arm64"
],
"outputPath": "dist/bin"
},
@ -30,7 +30,7 @@
"license": "ISC",
"devDependencies": {
"@faker-js/faker": "^8.2.0",
"@types/cli-progress": "^3.11.4",
"@types/cli-progress": "^3.11.5",
"@types/node": "20.8.10",
"dotenv-cli": "^7.3.0",
"esbuild": "^0.19.4",

View file

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

View file

@ -1,4 +1,4 @@
ARG NODE_VERSION="18.16"
ARG NODE_VERSION="20.10"
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: 'node18',
target: 'node20',
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, generateSystemEnvFile, generateTlsCertificates } from '@/lib/system';
import { copySystemFiles, ensureFilePermissions, generateSystemEnvFile, generateTlsCertificates } from '@/lib/system';
import { runPostgresMigrations } from '@/lib/migrations';
import { startWorker } from './watcher/watcher';
import { logger } from '@/lib/logger';
@ -30,6 +30,9 @@ 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,16 +259,7 @@ export const generateTlsCertificates = async (data: { domain?: string }) => {
};
export const ensureFilePermissions = async () => {
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 filesAndFolders = [path.join(ROOT_FOLDER, 'state'), path.join(ROOT_FOLDER, 'traefik')];
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 } from './repo.helpers';
import { getRepoHash, getRepoBaseUrlAndBranch } from './repo.helpers';
import { logger } from '@/lib/logger';
export class RepoExecutors {
@ -26,21 +26,32 @@ export class RepoExecutors {
/**
* Given a repo url, clone it to the repos folder if it doesn't exist
*
* @param {string} repoUrl
* @param {string} url
*/
public cloneRepo = async (repoUrl: string) => {
public cloneRepo = async (url: string) => {
try {
const repoHash = getRepoHash(repoUrl);
// 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 repoPath = path.join('/app', 'repos', repoHash);
if (await pathExists(repoPath)) {
this.logger.info(`Repo ${repoUrl} already exists`);
this.logger.info(`Repo ${url} already exists`);
return { success: true, message: '' };
}
this.logger.info(`Cloning repo ${repoUrl} to ${repoPath}`);
const [repoUrl, branch] = getRepoBaseUrlAndBranch(url);
await execAsync(`git clone ${repoUrl} ${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);
this.logger.info(`Cloned repo ${repoUrl} to ${repoPath}`);
return { success: true, message: '' };

View file

@ -10,3 +10,18 @@ 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,16 +121,12 @@ if ! command -v docker >/dev/null; then
install_docker "${OS}"
docker_result=$?
if [[ docker_result -eq 0 ]]; then
echo "Docker installed"
else
if [[ docker_result -ne 0 ]]; then
echo "Your system ${OS} is not supported trying with sub_os ${SUB_OS}"
install_docker "${SUB_OS}"
docker_sub_result=$?
if [[ docker_sub_result -eq 0 ]]; then
echo "Docker installed"
else
if [[ docker_sub_result -ne 0 ]]; then
echo "Your system ${SUB_OS} is not supported please install docker manually"
exit 1
fi
@ -138,11 +134,15 @@ 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 { Inter } from 'next/font/google';
import { GeistSans } from 'geist/font/sans';
import merge from 'lodash.merge';
import { NextIntlClientProvider } from 'next-intl';
import { getConfig } from '@/server/core/TipiConfig';
@ -13,11 +13,6 @@ 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',
@ -35,7 +30,7 @@ export default async function RootLayout({ children }: { children: React.ReactNo
const { allowAutoThemes } = getConfig();
return (
<html lang={locale} className={clsx(inter.className, 'border-top-wide border-primary')}>
<html lang={locale} className={clsx(GeistSans.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, config: { TEST_FIELD: 'test' } }, appConfig, db);
await insertApp({ version: 12, status: 'running', 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('stopped');
expect(app?.status).toBe('running');
});
it("Should throw if app doesn't exist", async () => {
@ -505,6 +505,16 @@ 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,6 +341,7 @@ 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 });
@ -355,14 +356,19 @@ export class AppServiceClass {
if (success) {
const appInfo = getAppInfo(app.id, app.status);
await this.queries.updateApp(id, { status: 'running', version: appInfo?.tipi_version });
await this.queries.updateApp(id, { version: appInfo?.tipi_version });
if (appStatusBeforeUpdate === 'running') {
await this.startApp(id);
} else {
await this.queries.updateApp(id, { status: appStatusBeforeUpdate });
}
} 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.queries.updateApp(id, { status: 'stopped' });
const updatedApp = await this.getApp(id);
return updatedApp;
};