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
56 changes: 28 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ COMMANDS:
build Compiles binaries
publish Publishes artifacts based on the configuration
deploy Deploys artifacts based on the configuration
release Release related commands
git Git related commands
version Displays the current version
help, h Shows a list of commands or help for one command
Expand Down Expand Up @@ -247,45 +248,44 @@ Error: command 'systemctl start myapp' failed: exit status 1

Once installed, you can run the following commands:

- **Build binaries:**

```bash
gcx build --config gcx.yaml
```
```bash
# Build binaries according to configuration
gcx build

This command:
# Publish artifacts to configured destinations
gcx publish

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
# Deploy artifacts using configured deployment settings
gcx deploy
gcx deploy --name production # Deploy specific configuration

- **Publish artifacts:**
# Show current git tag version
gcx git version

```bash
gcx publish --config gcx.yaml
```
# Generate a changelog between current and previous git tags
gcx release changelog

Uploads all files from the output directory to configured destinations (S3 or SSH).
# Show gcx version information
gcx version
```

- **Deploy:**
The changelog command generates a markdown-formatted list of changes between the current and previous git tags, including:

```bash
# Deploy all configurations
gcx deploy --config gcx.yaml
- List of changes with commit messages
- Author of each change
- Short commit hash
- Full changelog comparison URL

# Deploy specific configuration
gcx deploy --config gcx.yaml --name production
```
Example changelog output:

Executes deployment commands on target servers via SSH.
```markdown
## What's Changed

- **Show version:**
- Add new feature by @author in abc1234
- Fix documentation by @another-author in def5678

```bash
gcx version
```
**Full Changelog**: https://github.com/user/repo/compare/v0.0.1...v0.0.2
```

## GitLab CI/CD Integration Example

Expand Down
86 changes: 86 additions & 0 deletions cmd/gcx/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,70 @@ func getGitTag() string {
return tag
}

// getPreviousGitTag returns the previous git tag before the current one
func getPreviousGitTag() string {
// Get all tags sorted by version
cmd := exec.Command("git", "tag", "-l", "--sort=-v:refname")
out, err := cmd.Output()
if err != nil {
log.Printf("Failed to get git tags: %v. Using default value 0.0.0", err)
return "0.0.0"
}

tags := strings.Split(strings.TrimSpace(string(out)), "\n")
if len(tags) < 2 {
log.Println("No previous tag found, using default value 0.0.0")
return "0.0.0"
}

// Current tag should be the first one, so return the second one
currentTag := getGitTag()
for i, tag := range tags {
if tag == currentTag && i+1 < len(tags) {
return tags[i+1]
}
}

return "0.0.0"
}

// getGitChangelog returns a markdown formatted changelog between two tags
func getGitChangelog(from, to string) (string, error) {
// Get the repository URL
remoteCmd := exec.Command("git", "config", "--get", "remote.origin.url")
remoteOut, err := remoteCmd.Output()
if err != nil {
return "", fmt.Errorf("failed to get remote URL: %w", err)
}

// Convert SSH URL to HTTPS URL if necessary
repoURL := strings.TrimSpace(string(remoteOut))
repoURL = strings.TrimSuffix(repoURL, ".git")
if strings.HasPrefix(repoURL, "git@") {
repoURL = strings.Replace(repoURL, ":", "/", 1)
repoURL = strings.Replace(repoURL, "git@", "https://", 1)
}

// Get all commits between tags
cmd := exec.Command("git", "log",
"--pretty=format:* %s by @%an in %h", // Format each commit as a markdown list item with author and short hash
fmt.Sprintf("%s..%s", from, to)) // From older to newer tag
out, err := cmd.Output()
if err != nil {
return "", fmt.Errorf("failed to get git log: %w", err)
}

// Create the final markdown
var sb strings.Builder
sb.WriteString("## What's Changed\n\n")
sb.WriteString(string(out) + "\n")
sb.WriteString("\n")
sb.WriteString(fmt.Sprintf("**Full Changelog**: %s/compare/%s...%s\n",
repoURL, from, to))

return sb.String(), nil
}

// buildBinaries performs cross-compilation of binaries according to the configuration.
func buildBinaries(cfg *Config) error {
// Execute hooks (e.g., "go mod tidy")
Expand Down Expand Up @@ -839,6 +903,28 @@ func main() {
return deployArtifacts(cfg, c.String("name"))
},
},
{
Name: "release",
Usage: "Release related commands",
Subcommands: []*cli.Command{
{
Name: "changelog",
Usage: "Generate a changelog between the current and previous git tags",
Action: func(c *cli.Context) error {
currentTag := getGitTag()
previousTag := getPreviousGitTag()

changelog, err := getGitChangelog(previousTag, currentTag)
if err != nil {
return fmt.Errorf("failed to generate changelog: %w", err)
}

fmt.Println(changelog)
return nil
},
},
},
},
{
Name: "git",
Usage: "Git related commands",
Expand Down