diff --git a/.github/workflows/renovate.yml b/.github/workflows/renovate.yml new file mode 100644 index 0000000..77d2c04 --- /dev/null +++ b/.github/workflows/renovate.yml @@ -0,0 +1,40 @@ +name: Renovate +on: + workflow_dispatch: + inputs: + log_level: + type: choice + description: Log level + default: INFO + options: + - DEBUG + - INFO + - WARN + - ERROR + - FATAL + schedule: + - cron: 0 2 * * * + +jobs: + renovate: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Install bun + uses: oven-sh/setup-bun@v2 + + - name: Install Renovate + run: bun install -g renovate re2 + + - name: Echo repository + run: echo ${{ github.repository }} + + - name: Run renovate + run: LOG_LEVEL=${{ github.event.inputs.log_level || 'INFO' }} renovate --token ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/apps/whoami/config.json b/apps/whoami/config.json new file mode 100644 index 0000000..c343963 --- /dev/null +++ b/apps/whoami/config.json @@ -0,0 +1,24 @@ +{ + "name": "Whoami", + "id": "whoami", + "available": true, + "short_desc": "Tiny Go server that prints os information and HTTP request to output.", + "author": "traefik", + "port": 8382, + "categories": [ + "utilities" + ], + "description": "Tiny Go webserver that prints OS information and HTTP request to output.", + "tipi_version": 1, + "version": "v1.11.0", + "source": "https://github.com/traefik/whoami", + "exposable": true, + "supported_architectures": [ + "arm64", + "amd64" + ], + "created_at": 1745082405284, + "updated_at": 1745082405284, + "dynamic_config": true, + "form_fields": [] +} diff --git a/apps/whoami/docker-compose.json b/apps/whoami/docker-compose.json new file mode 100644 index 0000000..2f6c4a1 --- /dev/null +++ b/apps/whoami/docker-compose.json @@ -0,0 +1,10 @@ +{ + "services": [ + { + "name": "whoami", + "image": "traefik/whoami:v1.11.0", + "isMain": true, + "internalPort": "80" + } + ] +} diff --git a/apps/whoami/metadata/description.md b/apps/whoami/metadata/description.md new file mode 100644 index 0000000..27cd734 --- /dev/null +++ b/apps/whoami/metadata/description.md @@ -0,0 +1,43 @@ +# Whoami + +Tiny Go webserver that prints OS information and HTTP request to output. + +## Usage + +### Paths + +#### `/[?wait=d]` + +Returns the whoami information (request and network information). + +The optional `wait` query parameter can be provided to tell the server to wait before sending the response. +The duration is expected in Go's [`time.Duration`](https://golang.org/pkg/time/#ParseDuration) format (e.g. `/?wait=100ms` to wait 100 milliseconds). + +The optional `env` query parameter can be set to `true` to add the environment variables to the response. + +#### `/api` + +Returns the whoami information (and some extra information) as JSON. + +The optional `env` query parameter can be set to `true` to add the environment variables to the response. + +#### `/bench` + +Always return the same response (`1`). + +#### `/data?size=n[&unit=u]` + +Creates a response with a size `n`. + +The unit of measure, if specified, accepts the following values: `KB`, `MB`, `GB`, `TB` (optional, default: bytes). + +#### `/echo` + +WebSocket echo. + +#### `/health` + +Heath check. + +- `GET`, `HEAD`, ...: returns a response with the status code defined by the `POST` +- `POST`: changes the status code of the `GET` (`HEAD`, ...) response. diff --git a/apps/whoami/metadata/logo.jpg b/apps/whoami/metadata/logo.jpg new file mode 100644 index 0000000..24ed99d Binary files /dev/null and b/apps/whoami/metadata/logo.jpg differ diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000..f7bcbff Binary files /dev/null and b/bun.lockb differ diff --git a/package.json b/package.json new file mode 100644 index 0000000..6223dc6 --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "name": "example-appstore", + "version": "1.0.0", + "description": "", + "main": "index.js", + "type": "module", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "@runtipi/common": "^0.8.0", + "@types/node": "^22.14.1" + } +} diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..8bb2ada --- /dev/null +++ b/renovate.json @@ -0,0 +1,59 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended" + ], + "addLabels": [ + "renovate" + ], + "automergeStrategy": "rebase", + "ignoreTests": true, + "customManagers": [ + { + "customType": "regex", + "fileMatch": [ + "^.*docker-compose\\.json$" + ], + "matchStrings": [ + "\"image\": \"(?.*?):(?.*?)\"," + ], + "datasourceTemplate": "docker" + } + ], + "packageRules": [ + { + "matchUpdateTypes": [ + "minor", + "patch", + "pin", + "digest" + ], + "automerge": true + }, + { + "matchDepTypes": [ + "devDependencies" + ], + "automerge": true + }, + { + "matchPackageNames": [ + "mariadb", + "mysql", + "monogdb", + "postgres", + "redis" + ], + "enabled": false + } + ], + "postUpgradeTasks": { + "commands": [ + "bun ./scripts/update-config.ts {{packageFile}} {{newVersion}}" + ], + "fileFilters": [ + "**/*" + ], + "executionMode": "update" + } +} diff --git a/scripts/update-config.ts b/scripts/update-config.ts new file mode 100644 index 0000000..42891c7 --- /dev/null +++ b/scripts/update-config.ts @@ -0,0 +1,35 @@ +import path from "node:path"; +import fs from "fs/promises"; + +const packageFile = process.argv[2]; +const newVersion = process.argv[3]; + +type AppConfig = { + tipi_version: string; + version: string; + updated_at: number; +}; + +const updateAppConfig = async (packageFile: string, newVersion: string) => { + try { + const packageRoot = path.dirname(packageFile); + const configPath = path.join(packageRoot, "config.json"); + + const config = await fs.readFile(configPath, "utf-8"); + const configParsed = JSON.parse(config) as AppConfig; + + configParsed.tipi_version = configParsed.tipi_version + 1; + configParsed.version = newVersion; + configParsed.updated_at = new Date().getTime(); + + await fs.writeFile(configPath, JSON.stringify(configParsed, null, 2)); + } catch (e) { + console.error(`Failed to update app config, error: ${e}`); + } +}; + +if (!packageFile || !newVersion) { + console.error("Usage: node update-config.js "); + process.exit(1); +} +updateAppConfig(packageFile, newVersion); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..216b3a6 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "esModuleInterop": true, + "skipLibCheck": true, + "target": "es2022", + "allowJs": true, + "resolveJsonModule": true, + "moduleDetection": "force", + "isolatedModules": true, + "verbatimModuleSyntax": true, + "strict": true, + "noUncheckedIndexedAccess": true, + "noImplicitOverride": true, + "module": "NodeNext", + "outDir": "dist", + "sourceMap": true, + "lib": [ + "es2022" + ] + } +}