Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
193 changes: 166 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@

## Features

- **Cross-compilation:** Build Go binaries for multiple OS/architecture combinations.
- **Automated publishing:** Upload build artifacts to S3 (including self-hosted endpoints).
- **Configuration driven:** Use a YAML config file (`.gcx.yaml`) to define build, archive, and publish settings.
- **Versioning:** Automatically determine the version using the current Git tag.
- **CI/CD friendly:** Easily integrate with CI pipelines (e.g., GitLab CI).
- 🔨 **Cross-compilation:** Build Go binaries for multiple OS/architecture combinations.
- 🚀 **Automated publishing:** Upload build artifacts to S3 (including self-hosted endpoints) or SSH.
- ⚙️ **Configuration driven:** Use a YAML config file (`gcx.yaml`) to define build, archive, and publish settings.
- 🏷️ **Versioning:** Automatically determine the version using the current Git tag.
- 🔄 **CI/CD friendly:** Easily integrate with CI pipelines (e.g., GitLab CI).
- 🎣 **Hooks system:** Execute commands before and after build process.
- 📦 **Archiving:** Create archives (tar.gz) of your binaries with customizable naming.
- 🚢 **Deployment:** Deploy your artifacts to servers via SSH with custom commands.
- 🔔 **Notifications:** Send deployment status alerts to multiple channels (Telegram, Slack, Discord, Teams) using Shoutrrr.

## Installation

Expand All @@ -28,61 +32,172 @@ docker pull sxwebdev/gcx:latest

## Configuration

Create a YAML configuration file named `.gcx.yaml` in your project root. An example configuration:
Create a YAML configuration file named `gcx.yaml` in your project root. An example configuration:

```yaml
version: 1

out_dir: dist

# Pre-build hooks
before:
hooks:
- go mod tidy

# Post-build hooks
after:
hooks:
- ./binary version
- echo "Build completed!"
- ./scripts/notify-telegram.sh "New build ready!"

# Build configuration
builds:
- main: ./cmd/myapp
env:
- CGO_ENABLED=0
goos:
- linux
- darwin
goarch:
- amd64
- arm64
flags:
- -trimpath
ldflags:
- -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}
- -s -w -X main.version={{.Version}} -X main.commit={{.Commit}}

# Archive configuration
archives:
- formats: ["tar.gz"]
name_template: "{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"

# Artifact publishing configuration
blobs:
- provider: s3
bucket: your-bucket-name
directory: "releases/{{.ProjectID}}/{{.Version}}"
region: us-west-1
endpoint: https://s3.example.com

- provider: ssh
server: "storage.example.com"
user: "deployer"
key_path: "~/.ssh/deploy_key"
directory: "/var/www/releases/{{.ProjectID}}/{{.Version}}"

# Deployment configuration
deploys:
- name: "production"
provider: "ssh"
server: "prod.example.com"
user: "deployer"
key_path: "~/.ssh/deploy_key"
commands:
- systemctl stop myapp
- cp /var/www/releases/myapp/latest/myapp /usr/local/bin/
- chmod +x /usr/local/bin/myapp
- systemctl start myapp
alerts:
urls:
- "telegram://token@telegram?channels=channel-1"
- "slack://token-a/token-b/token-c"
- "discord://token@channel"
- "teams://token-a/token-b/token-c"

- name: "staging"
provider: "ssh"
server: "staging.example.com"
user: "deployer"
key_path: "~/.ssh/deploy_key"
commands:
- docker-compose -f /opt/myapp/docker-compose.yml down
- cp /var/www/releases/myapp/latest/myapp /opt/myapp/
- docker-compose -f /opt/myapp/docker-compose.yml up -d
alerts:
urls:
- "telegram://token@telegram?channels=staging-alerts"
- "slack://token-a/token-b/token-c"
```

### Template Variables

- **out_dir:** Sets the output directory for build artifacts (default is `dist`).
- **Version:** Automatically set from the current Git tag. If no tag is found, defaults to `0.0.0` (with a log message).
- **ProjectID:** If the `PROJECT_ID` environment variable is not set, the tool uses the name of the current working directory.
Available in various template strings throughout the configuration:

- **Version:** Current Git tag (defaults to `0.0.0` if no tag found)
- **Binary:** Name of the binary being built
- **Os:** Target operating system
- **Arch:** Target architecture
- **ProjectID:** Project identifier (from env or directory name)

## Environment Variables

Set the following environment variables (either in your system or in a `.env` file):

- `AWS_ACCESS_KEY_ID` - Your AWS access key.
- `AWS_SECRET_ACCESS_KEY` - Your AWS secret key.
- `AWS_ACCESS_KEY_ID` - Your AWS access key (for S3 provider)
- `AWS_SECRET_ACCESS_KEY` - Your AWS secret key (for S3 provider)
- `PROJECT_ID` (optional) - Your project identifier. If not provided, the current directory name is used.

You can also set additional variables required for your build or publish process.
## Alerts Configuration

The tool supports sending deployment status notifications using [shoutrrr](https://containrrr.dev/shoutrrr/). You can configure alerts for each deployment to notify different channels about success or failure of the deployment.

### Supported Services

- Telegram
- Slack
- Discord
- Microsoft Teams
- And many more (see [shoutrrr services](https://containrrr.dev/shoutrrr/services/overview/))

### URL Formats

Here are examples of URL formats for different services:

```yaml
alerts:
urls:
# Telegram
- "telegram://token@telegram?channels=channel-1,channel-2"

# Slack
- "slack://token-a/token-b/token-c"

# Discord
- "discord://token@channel"

# Microsoft Teams
- "teams://token-a/token-b/token-c"

# Generic Webhook
- "generic://example.com/webhook?token=token"
```

### Alert Message Format

The alert message includes:

- Application name (from deploy configuration)
- Version (current Git tag)
- Deployment status (Success/Failed)
- Error details (in case of failure)

Example success message:

```text
Deployment Status Update
Application: myapp-production
Version: v1.2.3
Status: Success
```

Example failure message:

```text
Deployment Status Update
Application: myapp-production
Version: v1.2.3
Status: Failed
Error: command 'systemctl start myapp' failed: exit status 1
```

## CLI Usage

Expand All @@ -91,40 +206,55 @@ Once installed, you can run the following commands:
- **Build binaries:**

```bash
gcx build --config .gcx.yaml
gcx build --config gcx.yaml
```

This command runs any pre-build hooks (e.g., `go mod tidy`) and compiles binaries for the specified targets, storing them in the `dist/` directory.
This command:

1. Runs pre-build hooks
2. Compiles binaries for specified targets
3. Creates archives if configured
4. Runs post-build hooks
5. Stores results in the output directory

- **Publish artifacts:**

```bash
gcx publish --config .gcx.yaml
gcx publish --config gcx.yaml
```

Uploads all files from the output directory to configured destinations (S3 or SSH).

- **Deploy:**

```bash
# Deploy all configurations
gcx deploy --config gcx.yaml

# Deploy specific configuration
gcx deploy --config gcx.yaml --name production
```

This command uploads all files from the `dist/` directory to the configured S3 bucket using the specified settings.
Executes deployment commands on target servers via SSH.

- **Show version:**

```bash
gcx version
```

This prints the current version, commit, and build date of the tool.

## GitLab CI/CD Integration Example

If the `gcx` image is available on Docker Hub, you can integrate it into your GitLab CI pipeline as follows:

```yaml
image: sxwebdev/gcx:latest

stages:
- build
- publish
- deploy

variables:
GCX_CONFIG: .gcx.yaml
GCX_CONFIG: gcx.yaml

build:
stage: build
Expand All @@ -140,13 +270,22 @@ publish:
- gcx publish --config $GCX_CONFIG
only:
- tags

deploy:
stage: deploy
script:
- gcx deploy --config $GCX_CONFIG --name production
only:
- tags
when: manual
```

In this pipeline:

- The `build` stage compiles binaries and stores them in `dist/`.
- The `publish` stage (triggered only when a Git tag is created) uploads the artifacts to S3.
- Ensure that all necessary environment variables (AWS credentials, etc.) are set in your GitLab CI/CD settings.
- The `build` stage compiles binaries, creates archives, and stores them in `dist/`
- The `publish` stage uploads artifacts to configured destinations
- The `deploy` stage (manual trigger) deploys the application to production
- Ensure all necessary environment variables are set in your GitLab CI/CD settings

## License

Expand Down
Loading