From 854c52faccec31c7659c9f53ec814e2913129202 Mon Sep 17 00:00:00 2001 From: sathirak <145209193+sathirak@users.noreply.github.com> Date: Thu, 24 Jul 2025 17:56:52 +0530 Subject: [PATCH 1/3] feat: enhance README with detailed deployment instructions and environment configuration --- README.md | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 113 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4864adf..55f0b18 100644 --- a/README.md +++ b/README.md @@ -8,13 +8,122 @@ Simply create a configuration file to define multiple services and databases to #### Currently supports -## Monitoring +- HTTP - Headers and all that +- Postgresql +- MySQL +- MariaDB +- MSSQL +- Redis +## Deployment + + +Deployment options: +- [Dockerfile](https://github.com/wavezync/pulse-bridge/blob/main/Dockerfile) – Self-hosted container registry or Docker Hub image +- Kubernetes + +### 💻 Deploy locally (Build from source) + +```bash +git clone https://github.com/wavezync/pulse-bridge.git +cd pulse-bridge +go run . +``` + +### 🐳 Deploy with Docker + +```bash +git clone https://github.com/wavezync/pulse-bridge.git +cd pulse-bridge +docker build -t pulse-bridge . +docker run -d -p 8080:8080 pulse-bridge +``` + +Update the [config.yml](https://github.com/wavezync/pulse-bridge/blob/main/config.yml) in the project root to add your services and databases. Then rebuild the binary or Docker image and run it. + +### 🚢 Deploy with Kubernetes + +There are many ways to deploy Pulse Bridge on Kubernetes. Below is a simple example using a Deployment, Service, and ConfigMap. + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: pulse-bridge +spec: + replicas: 1 + selector: + matchLabels: + app: pulse-bridge + template: + metadata: + labels: + app: pulse-bridge + spec: + containers: + - name: pulse-bridge + image: wavezync/pulse-bridge:latest # Replace with your image if needed (recommended) + ports: + - containerPort: 8080 + env: + - name: PULSE_BRIDGE_CONFIG + value: "/config/config.yml" + volumeMounts: + - name: config-volume + mountPath: /config + volumes: + - name: config-volume + configMap: + name: pulse-bridge-config +--- +apiVersion: v1 +kind: Service +metadata: + name: pulse-bridge +spec: + selector: + app: pulse-bridge + ports: + - protocol: TCP + port: 8080 + targetPort: 8080 +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: pulse-bridge-config +data: + config.yml: | + # Paste your Pulse Bridge YAML config here. See the guide below for configuration details. +``` + + +### Environment Configuration + +1. .env file: + +A .env file is **optional** but can be configured: + +```bash +PULSE_BRIDGE_CONFIG=mycustomconfig.yml # Sets the custom configuration file path, defaults to config.yml +HOST=0.0.0.0 # Defaults to 0.0.0.0 +PORT=8080 # Defaults to 8080 +``` + +2. CLI arguments: + +```bash +pb --config=mycustomconfig.yml --port=8080 --host=0.0.0.0 +``` + +> **Note:** CLI arguments take priority over `.env` file settings. CLI > .env -## Configuration +## Usage + +### Configuring your services The configuration file is a YAML file where you can define the services and databases you want to monitor. @@ -95,7 +204,8 @@ monitors: query: "SELECT 1" ``` -## Monitoring +### Monitoring + You can check the status of your service from the pulse bridge API at the routes: From d660c2cfc03825e1ef4d4c8ca071b9b6cba48a1c Mon Sep 17 00:00:00 2001 From: sathirak <145209193+sathirak@users.noreply.github.com> Date: Mon, 28 Jul 2025 09:54:38 +0530 Subject: [PATCH 2/3] fix: update Docker deployment instructions to use pre-built image --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 55f0b18..672420d 100644 --- a/README.md +++ b/README.md @@ -33,10 +33,8 @@ go run . ### 🐳 Deploy with Docker ```bash -git clone https://github.com/wavezync/pulse-bridge.git -cd pulse-bridge -docker build -t pulse-bridge . -docker run -d -p 8080:8080 pulse-bridge +docker pull ghcr.io/wavezync/pulsebridge:latest +docker run -d -p 8080:8080 ghcr.io/wavezync/pulsebridge:latest ``` Update the [config.yml](https://github.com/wavezync/pulse-bridge/blob/main/config.yml) in the project root to add your services and databases. Then rebuild the binary or Docker image and run it. From 109beff3abdeed2d6bb81a8506982347106cd0b0 Mon Sep 17 00:00:00 2001 From: sathirak <145209193+sathirak@users.noreply.github.com> Date: Mon, 28 Jul 2025 10:56:27 +0530 Subject: [PATCH 3/3] feat: add version command to display application version and build info --- cmd/root.go | 15 ++++-- internal/version/version.go | 103 ++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 internal/version/version.go diff --git a/cmd/root.go b/cmd/root.go index df07dcd..bfdab2b 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,8 +1,10 @@ package cmd import ( + "fmt" "wavezync/pulse-bridge/cmd/pulsebridge" "wavezync/pulse-bridge/internal/env" + "wavezync/pulse-bridge/internal/version" "github.com/rs/zerolog" "github.com/rs/zerolog/log" @@ -16,10 +18,16 @@ var ( ) var rootCmd = &cobra.Command{ - Use: "pulsebridge", - Short: "pulsebridge is a powerful uptime monitoring tool", - Long: `pulsebridge exposes internal service status via HTTP, enabling seamless integration with external monitoring tools like Atlassian Statuspage.`, + Use: "pulsebridge", + Short: "pulsebridge is a powerful uptime monitoring tool", + Long: `pulsebridge exposes internal service status via HTTP, enabling seamless integration with external monitoring tools like Atlassian Statuspage.`, RunE: func(cmd *cobra.Command, args []string) error { + versionFlag, _ := cmd.Flags().GetBool("version") + if versionFlag { + fmt.Println(version.GetVersionWithBuildInfo()) + return nil + } + envConfig := env.Init() if cmd.Flags().Changed("config") { @@ -40,6 +48,7 @@ func init() { rootCmd.PersistentFlags().StringVar(&configPath, "config", "config.yml", "Path to configuration file") rootCmd.PersistentFlags().StringVar(&host, "host", "0.0.0.0", "Host address to bind the server") rootCmd.PersistentFlags().IntVar(&port, "port", 8080, "Port to run the server") + rootCmd.PersistentFlags().BoolP("version", "v", false, "Print the version and exit") } func Execute() { diff --git a/internal/version/version.go b/internal/version/version.go new file mode 100644 index 0000000..76a1605 --- /dev/null +++ b/internal/version/version.go @@ -0,0 +1,103 @@ +package version + +import ( + "fmt" + "runtime" + "runtime/debug" + "strings" +) + +var ( + version string + tag string + commit string + dirty bool +) + +func init() { + // Always attempt to get build info from the Go runtime, regardless of build type. + if info, ok := debug.ReadBuildInfo(); ok { + if version == "" { + // If version wasn't set via ldflags, try to get it from VCS info + version = getVersionFromVCS(info) + } + commit = getCommit(info) + dirty = getDirty(info) + } + + // Fallback version if nothing else is available + if version == "" { + version = "dev" + } +} + +func getVersionFromVCS(info *debug.BuildInfo) string { + for _, setting := range info.Settings { + if setting.Key == "vcs.revision" { + // Use commit hash as version if no proper version is available + if len(setting.Value) >= 7 { + return "dev-" + setting.Value[:7] + } + } + } + return "" +} + +func getDirty(info *debug.BuildInfo) bool { + for _, setting := range info.Settings { + if setting.Key == "vcs.modified" { + return setting.Value == "true" + } + } + return false +} + +func getCommit(info *debug.BuildInfo) string { + for _, setting := range info.Settings { + if setting.Key == "vcs.revision" { + return setting.Value[:7] + } + } + return "" +} + +// GetVersion returns the version of pulsebridge. This should be injected at build time +// using: -ldflags="-X 'wavezync/pulse-bridge/internal/version.version=vX.X.X'". +// If not provided, it will attempt to derive a version from VCS info. +func GetVersion() string { + return version +} + +// GetVersionWithBuildInfo returns detailed version information including +// commit hash, dirty status, and Go version. This will work when built +// within a Git checkout. +func GetVersionWithBuildInfo() string { + var parts []string + + // Add the main version + parts = append(parts, fmt.Sprintf("Version: %s", version)) + + // Add build metadata + var buildMetadata []string + if tag != "" { + buildMetadata = append(buildMetadata, tag) + } + if commit != "" { + buildMetadata = append(buildMetadata, commit) + } + if dirty { + buildMetadata = append(buildMetadata, "dirty") + } + + if len(buildMetadata) > 0 { + parts = append(parts, fmt.Sprintf("Build: %s", strings.Join(buildMetadata, "."))) + } + + // Add Go version + parts = append(parts, fmt.Sprintf("Go: %s", runtime.Version())) + + // Add architecture + parts = append(parts, fmt.Sprintf("Platform: %s/%s", runtime.GOOS, runtime.GOARCH)) + + return strings.Join(parts, "\n") +}