feat: add check server command

This commit is contained in:
Mauricio Siu
2024-06-03 21:55:29 -06:00
parent 85fd1f2c3e
commit de871490d7
27 changed files with 5907 additions and 1 deletions

1
.eslintignore Normal file
View File

@@ -0,0 +1 @@
/dist

3
.eslintrc.json Normal file
View File

@@ -0,0 +1,3 @@
{
"extends": ["oclif", "oclif-typescript", "prettier"]
}

56
.github/workflows/onPushToMain.yml vendored Normal file
View File

@@ -0,0 +1,56 @@
# test
name: version, tag and github release
on:
push:
branches: [main]
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- name: Check if version already exists
id: version-check
run: |
package_version=$(node -p "require('./package.json').version")
exists=$(gh api repos/${{ github.repository }}/releases/tags/v$package_version >/dev/null 2>&1 && echo "true" || echo "")
if [ -n "$exists" ];
then
echo "Version v$package_version already exists"
echo "::warning file=package.json,line=1::Version v$package_version already exists - no release will be created. If you want to create a new release, please update the version in package.json and push again."
echo "skipped=true" >> $GITHUB_OUTPUT
else
echo "Version v$package_version does not exist. Creating release..."
echo "skipped=false" >> $GITHUB_OUTPUT
echo "tag=v$package_version" >> $GITHUB_OUTPUT
fi
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
- name: Setup git
if: ${{ steps.version-check.outputs.skipped == 'false' }}
run: |
git config --global user.email ${{ secrets.GH_EMAIL }}
git config --global user.name ${{ secrets.GH_USERNAME }}
- name: Generate oclif README
if: ${{ steps.version-check.outputs.skipped == 'false' }}
id: oclif-readme
run: |
pnpm install
pnpm exec oclif readme
if [ -n "$(git status --porcelain)" ]; then
git add .
git commit -am "chore: update README.md"
git push -u origin ${{ github.ref_name }}
fi
- name: Create Github Release
uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5
if: ${{ steps.version-check.outputs.skipped == 'false' }}
with:
name: ${{ steps.version-check.outputs.tag }}
tag: ${{ steps.version-check.outputs.tag }}
commit: ${{ github.ref_name }}
token: ${{ secrets.GH_TOKEN }}
skipIfReleaseExists: true

18
.github/workflows/onRelease.yml vendored Normal file
View File

@@ -0,0 +1,18 @@
name: publish
on:
release:
types: [released]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: latest
- run: pnpm install
- uses: JS-DevTools/npm-publish@19c28f1ef146469e409470805ea4279d47c3d35c
with:
token: ${{ secrets.NPM_TOKEN }}

23
.github/workflows/test.yml vendored Normal file
View File

@@ -0,0 +1,23 @@
name: tests
on:
push:
branches-ignore: [main]
workflow_dispatch:
jobs:
unit-tests:
strategy:
matrix:
os: ['ubuntu-latest', 'windows-latest']
node_version: [lts/-1, lts/*, latest]
fail-fast: false
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node_version }}
cache: pnpm
- run: pnpm install
- run: pnpm run build
- run: pnpm run test

14
.gitignore vendored Normal file
View File

@@ -0,0 +1,14 @@
*-debug.log
*-error.log
**/.DS_Store
/.idea
/dist
/tmp
/node_modules
oclif.manifest.json
yarn.lock
package-lock.json

15
.mocharc.json Normal file
View File

@@ -0,0 +1,15 @@
{
"require": [
"ts-node/register"
],
"watch-extensions": [
"ts"
],
"recursive": true,
"reporter": "spec",
"timeout": 60000,
"node-option": [
"loader=ts-node/esm",
"experimental-specifier-resolution=node"
]
}

1
.prettierrc.json Normal file
View File

@@ -0,0 +1 @@
"@oclif/prettier-config"

20
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,20 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "attach",
"name": "Attach",
"port": 9229,
"skipFiles": ["<node_internals>/**"]
},
{
"type": "node",
"request": "launch",
"name": "Execute Command",
"skipFiles": ["<node_internals>/**"],
"program": "${workspaceFolder}/bin/dev",
"args": ["hello", "world"]
}
]
}

3
bin/dev.cmd Normal file
View File

@@ -0,0 +1,3 @@
@echo off
node --loader ts-node/esm --no-warnings=ExperimentalWarning "%~dp0\dev" %*

6
bin/dev.js Executable file
View File

@@ -0,0 +1,6 @@
#!/usr/bin/env -S node --loader ts-node/esm --no-warnings=ExperimentalWarning
// eslint-disable-next-line n/shebang
import {execute} from '@oclif/core'
await execute({development: true, dir: import.meta.url})

3
bin/run.cmd Normal file
View File

@@ -0,0 +1,3 @@
@echo off
node "%~dp0\run" %*

5
bin/run.js Executable file
View File

@@ -0,0 +1,5 @@
#!/usr/bin/env node
import {execute} from '@oclif/core'
await execute({dir: import.meta.url})

74
package.json Normal file
View File

@@ -0,0 +1,74 @@
{
"name": "dokploy",
"description": "A CLI to manage dokploy server remotely",
"version": "0.0.0",
"author": "Mauricio Siu",
"bin": {
"dokploy": "./bin/run.js"
},
"bugs": "https://github.com/Dokploy/cli/issues",
"dependencies": {
"@oclif/core": "^3",
"@oclif/plugin-help": "^6",
"@oclif/plugin-plugins": "^5",
"axios": "^1.7.2"
},
"devDependencies": {
"@oclif/prettier-config": "^0.2.1",
"@oclif/test": "^4",
"@types/chai": "^4",
"@types/mocha": "^10",
"@types/node": "^18",
"chai": "^4",
"eslint": "^8",
"eslint-config-oclif": "^5",
"eslint-config-oclif-typescript": "^3",
"eslint-config-prettier": "^9",
"mocha": "^10",
"oclif": "^4",
"shx": "^0.3.3",
"ts-node": "^10",
"typescript": "^5"
},
"engines": {
"node": ">=18.0.0"
},
"files": [
"/bin",
"/dist",
"/oclif.manifest.json"
],
"homepage": "https://github.com/Dokploy/cli",
"keywords": [
"oclif"
],
"license": "MIT",
"main": "dist/index.js",
"type": "module",
"oclif": {
"bin": "dokploy",
"dirname": "dokploy",
"commands": "./dist/commands",
"plugins": [
"@oclif/plugin-help",
"@oclif/plugin-plugins"
],
"topicSeparator": " ",
"topics": {
"hello": {
"description": "Say hello to the world and others"
}
}
},
"repository": "Dokploy/cli",
"scripts": {
"build": "shx rm -rf dist && tsc -b",
"lint": "eslint . --ext .ts",
"postpack": "shx rm -f oclif.manifest.json",
"posttest": "pnpm run lint",
"prepack": "oclif manifest && oclif readme",
"test": "mocha --forbid-only \"test/**/*.test.ts\"",
"version": "oclif readme && git add README.md"
},
"types": "dist/index.d.ts"
}

5071
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

397
readme.md
View File

@@ -1 +1,396 @@
# cli
dokploy
=================
A CLI to manage dokploy server remotely
[![oclif](https://img.shields.io/badge/cli-oclif-brightgreen.svg)](https://oclif.io)
[![Version](https://img.shields.io/npm/v/dokploy.svg)](https://npmjs.org/package/dokploy)
[![Downloads/week](https://img.shields.io/npm/dw/dokploy.svg)](https://npmjs.org/package/dokploy)
<!-- toc -->
* [Usage](#usage)
* [Commands](#commands)
<!-- tocstop -->
# Usage
<!-- usage -->
```sh-session
$ npm install -g dokploy
$ dokploy COMMAND
running command...
$ dokploy (--version)
dokploy/0.0.0 darwin-arm64 node-v18.18.0
$ dokploy --help [COMMAND]
USAGE
$ dokploy COMMAND
...
```
<!-- usagestop -->
# Commands
<!-- commands -->
* [`dokploy hello PERSON`](#dokploy-hello-person)
* [`dokploy hello world`](#dokploy-hello-world)
* [`dokploy help [COMMAND]`](#dokploy-help-command)
* [`dokploy plugins`](#dokploy-plugins)
* [`dokploy plugins add PLUGIN`](#dokploy-plugins-add-plugin)
* [`dokploy plugins:inspect PLUGIN...`](#dokploy-pluginsinspect-plugin)
* [`dokploy plugins install PLUGIN`](#dokploy-plugins-install-plugin)
* [`dokploy plugins link PATH`](#dokploy-plugins-link-path)
* [`dokploy plugins remove [PLUGIN]`](#dokploy-plugins-remove-plugin)
* [`dokploy plugins reset`](#dokploy-plugins-reset)
* [`dokploy plugins uninstall [PLUGIN]`](#dokploy-plugins-uninstall-plugin)
* [`dokploy plugins unlink [PLUGIN]`](#dokploy-plugins-unlink-plugin)
* [`dokploy plugins update`](#dokploy-plugins-update)
## `dokploy hello PERSON`
Say hello
```
USAGE
$ dokploy hello PERSON -f <value>
ARGUMENTS
PERSON Person to say hello to
FLAGS
-f, --from=<value> (required) Who is saying hello
DESCRIPTION
Say hello
EXAMPLES
$ dokploy hello friend --from oclif
hello friend from oclif! (./src/commands/hello/index.ts)
```
_See code: [src/commands/hello/index.ts](https://github.com/Dokploy/cli/blob/v0.0.0/src/commands/hello/index.ts)_
## `dokploy hello world`
Say hello world
```
USAGE
$ dokploy hello world
DESCRIPTION
Say hello world
EXAMPLES
$ dokploy hello world
hello world! (./src/commands/hello/world.ts)
```
_See code: [src/commands/hello/world.ts](https://github.com/Dokploy/cli/blob/v0.0.0/src/commands/hello/world.ts)_
## `dokploy help [COMMAND]`
Display help for dokploy.
```
USAGE
$ dokploy help [COMMAND...] [-n]
ARGUMENTS
COMMAND... Command to show help for.
FLAGS
-n, --nested-commands Include all nested commands in the output.
DESCRIPTION
Display help for dokploy.
```
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v6.1.0/src/commands/help.ts)_
## `dokploy plugins`
List installed plugins.
```
USAGE
$ dokploy plugins [--json] [--core]
FLAGS
--core Show core plugins.
GLOBAL FLAGS
--json Format output as json.
DESCRIPTION
List installed plugins.
EXAMPLES
$ dokploy plugins
```
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.2.1/src/commands/plugins/index.ts)_
## `dokploy plugins add PLUGIN`
Installs a plugin into dokploy.
```
USAGE
$ dokploy plugins add PLUGIN... [--json] [-f] [-h] [-s | -v]
ARGUMENTS
PLUGIN... Plugin to install.
FLAGS
-f, --force Force npm to fetch remote resources even if a local copy exists on disk.
-h, --help Show CLI help.
-s, --silent Silences npm output.
-v, --verbose Show verbose npm output.
GLOBAL FLAGS
--json Format output as json.
DESCRIPTION
Installs a plugin into dokploy.
Uses bundled npm executable to install plugins into /Users/mauricio/.local/share/dokploy
Installation of a user-installed plugin will override a core plugin.
Use the DOKPLOY_NPM_LOG_LEVEL environment variable to set the npm loglevel.
Use the DOKPLOY_NPM_REGISTRY environment variable to set the npm registry.
ALIASES
$ dokploy plugins add
EXAMPLES
Install a plugin from npm registry.
$ dokploy plugins add myplugin
Install a plugin from a github url.
$ dokploy plugins add https://github.com/someuser/someplugin
Install a plugin from a github slug.
$ dokploy plugins add someuser/someplugin
```
## `dokploy plugins:inspect PLUGIN...`
Displays installation properties of a plugin.
```
USAGE
$ dokploy plugins inspect PLUGIN...
ARGUMENTS
PLUGIN... [default: .] Plugin to inspect.
FLAGS
-h, --help Show CLI help.
-v, --verbose
GLOBAL FLAGS
--json Format output as json.
DESCRIPTION
Displays installation properties of a plugin.
EXAMPLES
$ dokploy plugins inspect myplugin
```
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.2.1/src/commands/plugins/inspect.ts)_
## `dokploy plugins install PLUGIN`
Installs a plugin into dokploy.
```
USAGE
$ dokploy plugins install PLUGIN... [--json] [-f] [-h] [-s | -v]
ARGUMENTS
PLUGIN... Plugin to install.
FLAGS
-f, --force Force npm to fetch remote resources even if a local copy exists on disk.
-h, --help Show CLI help.
-s, --silent Silences npm output.
-v, --verbose Show verbose npm output.
GLOBAL FLAGS
--json Format output as json.
DESCRIPTION
Installs a plugin into dokploy.
Uses bundled npm executable to install plugins into /Users/mauricio/.local/share/dokploy
Installation of a user-installed plugin will override a core plugin.
Use the DOKPLOY_NPM_LOG_LEVEL environment variable to set the npm loglevel.
Use the DOKPLOY_NPM_REGISTRY environment variable to set the npm registry.
ALIASES
$ dokploy plugins add
EXAMPLES
Install a plugin from npm registry.
$ dokploy plugins install myplugin
Install a plugin from a github url.
$ dokploy plugins install https://github.com/someuser/someplugin
Install a plugin from a github slug.
$ dokploy plugins install someuser/someplugin
```
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.2.1/src/commands/plugins/install.ts)_
## `dokploy plugins link PATH`
Links a plugin into the CLI for development.
```
USAGE
$ dokploy plugins link PATH [-h] [--install] [-v]
ARGUMENTS
PATH [default: .] path to plugin
FLAGS
-h, --help Show CLI help.
-v, --verbose
--[no-]install Install dependencies after linking the plugin.
DESCRIPTION
Links a plugin into the CLI for development.
Installation of a linked plugin will override a user-installed or core plugin.
e.g. If you have a user-installed or core plugin that has a 'hello' command, installing a linked plugin with a 'hello'
command will override the user-installed or core plugin implementation. This is useful for development work.
EXAMPLES
$ dokploy plugins link myplugin
```
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.2.1/src/commands/plugins/link.ts)_
## `dokploy plugins remove [PLUGIN]`
Removes a plugin from the CLI.
```
USAGE
$ dokploy plugins remove [PLUGIN...] [-h] [-v]
ARGUMENTS
PLUGIN... plugin to uninstall
FLAGS
-h, --help Show CLI help.
-v, --verbose
DESCRIPTION
Removes a plugin from the CLI.
ALIASES
$ dokploy plugins unlink
$ dokploy plugins remove
EXAMPLES
$ dokploy plugins remove myplugin
```
## `dokploy plugins reset`
Remove all user-installed and linked plugins.
```
USAGE
$ dokploy plugins reset [--hard] [--reinstall]
FLAGS
--hard Delete node_modules and package manager related files in addition to uninstalling plugins.
--reinstall Reinstall all plugins after uninstalling.
```
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.2.1/src/commands/plugins/reset.ts)_
## `dokploy plugins uninstall [PLUGIN]`
Removes a plugin from the CLI.
```
USAGE
$ dokploy plugins uninstall [PLUGIN...] [-h] [-v]
ARGUMENTS
PLUGIN... plugin to uninstall
FLAGS
-h, --help Show CLI help.
-v, --verbose
DESCRIPTION
Removes a plugin from the CLI.
ALIASES
$ dokploy plugins unlink
$ dokploy plugins remove
EXAMPLES
$ dokploy plugins uninstall myplugin
```
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.2.1/src/commands/plugins/uninstall.ts)_
## `dokploy plugins unlink [PLUGIN]`
Removes a plugin from the CLI.
```
USAGE
$ dokploy plugins unlink [PLUGIN...] [-h] [-v]
ARGUMENTS
PLUGIN... plugin to uninstall
FLAGS
-h, --help Show CLI help.
-v, --verbose
DESCRIPTION
Removes a plugin from the CLI.
ALIASES
$ dokploy plugins unlink
$ dokploy plugins remove
EXAMPLES
$ dokploy plugins unlink myplugin
```
## `dokploy plugins update`
Update installed plugins.
```
USAGE
$ dokploy plugins update [-h] [-v]
FLAGS
-h, --help Show CLI help.
-v, --verbose
DESCRIPTION
Update installed plugins.
```
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.2.1/src/commands/plugins/update.ts)_
<!-- commandsstop -->

View File

@@ -0,0 +1,29 @@
import { Command, Flags } from "@oclif/core";
import * as fs from "node:fs";
import * as path from "node:path";
const configPath = path.join(__dirname, "..", "..", "config.json");
export default class Authenticate extends Command {
static description = "Authenticate the user by saving server URL and token";
static flags = {
token: Flags.string({
char: "t",
description: "Authentication token",
required: true,
}),
url: Flags.string({ char: "u", description: "Server URL", required: true }),
};
async run() {
const { flags } = await this.parse(Authenticate);
const config = {
token: flags.token,
url: flags.url,
};
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
this.log("Authentication details saved successfully.");
}
}

View File

@@ -0,0 +1,30 @@
import {Args, Command, Flags} from '@oclif/core'
export default class CheckServer extends Command {
static override args = {
file: Args.string({description: 'file to read'}),
}
static override description = 'describe the command here'
static override examples = [
'<%= config.bin %> <%= command.id %>',
]
static override flags = {
// flag with no value (-f, --force)
force: Flags.boolean({char: 'f'}),
// flag with a value (-n, --name=VALUE)
name: Flags.string({char: 'n', description: 'name to print'}),
}
public async run(): Promise<void> {
const {args, flags} = await this.parse(CheckServer)
const name = flags.name ?? 'world'
this.log(`hello ${name} from /Users/mauricio/Documents/Github/Personal/cli/src/commands/check-server.ts`)
if (args.file && flags.force) {
this.log(`you input --force and --file: ${args.file}`)
}
}
}

View File

@@ -0,0 +1,29 @@
import { Command, Flags } from "@oclif/core";
export default class Greet extends Command {
static args = {
// Puedes agregar argumentos adicionales si lo necesitas
};
static description = "Greet the user with a message";
static examples = [
`<%= config.bin %> <%= command.id %> --name=Mau
hello Mau!
`,
];
static flags = {
name: Flags.string({
char: "n",
description: "name to greet",
required: false,
}),
};
async run(): Promise<void> {
const { flags } = await this.parse(Greet);
const name = flags.name ?? "user";
this.log(`hello ${name}!`);
}
}

View File

@@ -0,0 +1,34 @@
import { Args, Command, Flags } from "@oclif/core";
export default class Hello extends Command {
static args = {
person: Args.string({
description: "Person to say hello to",
required: true,
}),
};
static description = "Say hello";
static examples = [
`<%= config.bin %> <%= command.id %> friend --from oclif
hello friend from oclif! (./src/commands/hello/index.ts)
`,
];
static flags = {
from: Flags.string({
char: "f",
description: "Who is saying hello",
required: true,
}),
};
async run(): Promise<void> {
const { args, flags } = await this.parse(Hello);
this.log(
`hello ${args.person} from ${flags.from}! (./src/commands/hello/index.ts)`,
);
}
}

View File

@@ -0,0 +1,19 @@
import {Command} from '@oclif/core'
export default class World extends Command {
static args = {}
static description = 'Say hello world'
static examples = [
`<%= config.bin %> <%= command.id %>
hello world! (./src/commands/hello/world.ts)
`,
]
static flags = {}
async run(): Promise<void> {
this.log('hello world! (./src/commands/hello/world.ts)')
}
}

1
src/index.ts Normal file
View File

@@ -0,0 +1 @@
export {run} from '@oclif/core'

View File

@@ -0,0 +1,14 @@
import {runCommand} from '@oclif/test'
import {expect} from 'chai'
describe('check-server', () => {
it('runs check-server cmd', async () => {
const {stdout} = await runCommand('check-server')
expect(stdout).to.contain('hello world')
})
it('runs check-server --name oclif', async () => {
const {stdout} = await runCommand('check-server --name oclif')
expect(stdout).to.contain('hello oclif')
})
})

View File

@@ -0,0 +1,9 @@
import {runCommand} from '@oclif/test'
import {expect} from 'chai'
describe('hello', () => {
it('runs hello', async () => {
const {stdout} = await runCommand('hello friend --from oclif')
expect(stdout).to.contain('hello friend from oclif!')
})
})

View File

@@ -0,0 +1,9 @@
import {runCommand} from '@oclif/test'
import {expect} from 'chai'
describe('hello world', () => {
it('runs hello world cmd', async () => {
const {stdout} = await runCommand('hello world')
expect(stdout).to.contain('hello world!')
})
})

9
test/tsconfig.json Normal file
View File

@@ -0,0 +1,9 @@
{
"extends": "../tsconfig",
"compilerOptions": {
"noEmit": true
},
"references": [
{"path": ".."}
]
}

15
tsconfig.json Normal file
View File

@@ -0,0 +1,15 @@
{
"compilerOptions": {
"declaration": true,
"module": "Node16",
"outDir": "dist",
"rootDir": "src",
"strict": true,
"target": "es2022",
"moduleResolution": "node16"
},
"include": ["./src/**/*"],
"ts-node": {
"esm": true
}
}