smyklot

module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 12, 2025 License: MIT

README

Smyklot

GitHub Actions bot for automated PR approvals and merges based on CODEOWNERS

Overview

Smyklot is a lightweight GitHub Actions bot that enables team members to approve and merge pull requests through simple commands, with permissions managed through GitHub's native .github/CODEOWNERS file.

Features

  • Command-based PR management via issue comments
  • Permission system using .github/CODEOWNERS
  • Flexible configuration (environment variables, CLI flags)
  • Automated feedback with emoji reactions
  • Security-first design following GitHub Actions best practices
  • Zero external dependencies - runs entirely on GitHub Actions
  • TDD implementation with 98 passing tests

Quick Start

Prerequisites
  • GitHub repository with Actions enabled
  • .github/CODEOWNERS file in your repository
Installation

Copy the workflow files to your repository:

# Copy workflows
cp .github/workflows/pr-commands.yml your-repo/.github/workflows/
cp .github/workflows/test.yml your-repo/.github/workflows/
Configuration
CODEOWNERS Setup

Create .github/CODEOWNERS in your repository:

# Global owners can approve/merge any PR
* @username1 @username2

Currently only global owners (* pattern) are supported. Path-specific owners will be added in Phase 2.

Bot Configuration

Smyklot supports multiple configuration sources with the following precedence:

CLI Flags > Environment Variables > Defaults

Available Options
Option Type Default Description
quiet_success boolean false Emoji reactions only
allowed_commands string list [] (all) Allowed commands list
command_aliases string map {} Command aliases
command_prefix string / Slash command prefix
disable_mentions boolean false Disable mentions
Configuration Methods
Environment Variables

Use SMYKLOT_ prefix with uppercase names:

# .github/workflows/pr-commands.yml
env:
  SMYKLOT_QUIET_SUCCESS: "true"
  SMYKLOT_ALLOWED_COMMANDS: "approve,merge"
  SMYKLOT_COMMAND_PREFIX: "!"
  SMYKLOT_DISABLE_MENTIONS: "false"
CLI Flags

Pass flags to the binary:

./smyklot-github-action \
  --quiet-success=true \
  --allowed-commands=approve,merge \
  --command-aliases='{"app":"approve","m":"merge"}' \
  --command-prefix="!" \
  --disable-mentions=false
Examples
Example 1: Quiet Mode

Only show emoji reactions, no success comments:

env:
  SMYKLOT_QUIET_SUCCESS: "true"

Result: User sees only ✅ reaction, no "PR Approved" comment.

Example 2: Custom Prefix

Use ! instead of / for commands:

env:
  SMYKLOT_COMMAND_PREFIX: "!"

Users can now use !approve and !merge.

Example 3: Command Aliases

Create shortcuts for commands:

env:
  SMYKLOT_COMMAND_ALIASES: '{"app":"approve","a":"approve","m":"merge"}'

Users can use /app, /a, or /m as shortcuts.

Example 4: Restrict Commands

Only allow approve command:

env:
  SMYKLOT_ALLOWED_COMMANDS: "approve"

The /merge command will be ignored.

Example 5: Disable Mentions

Only allow slash commands:

env:
  SMYKLOT_DISABLE_MENTIONS: "true"

@smyklot approve will no longer work, only /approve.

Usage

Commands

Smyklot responds to these commands in PR comments:

Command Alias Description
/approve @smyklot approve Approve the pull request
/merge @smyklot merge Merge the pull request
Example: Approving a PR

Comment on any pull request:

/approve

Smyklot will:

  1. Check if you're a global owner in .github/CODEOWNERS
  2. Approve the PR via GitHub API
  3. Add ✅ reaction to your comment
Example: Merging a PR

Comment on any pull request:

/merge

Smyklot will:

  1. Check if you're a global owner
  2. Verify the PR is mergeable
  3. Merge the PR via GitHub API
  4. Add ✅ reaction to your comment
Error Handling

If you're not authorized, Smyklot will:

  • Add ❌ reaction to your comment
  • Post a comment explaining who can approve/merge

Development

Requirements
  • Go 1.25+
  • mise for tool management
  • Task for task automation
Setup
# Clone repository
git clone https://github.com/bartsmykla/smyklot.git
cd smyklot

# Install tools
mise install

# Download dependencies
task deps

# Run tests
task test
Project Structure
smyklot/
├── cmd/
│   └── github-action/       # GitHub Actions entrypoint
├── pkg/
│   ├── commands/            # Command parser
│   ├── feedback/            # User feedback system
│   ├── github/              # GitHub API client
│   └── permissions/         # CODEOWNERS parser & checker
├── .github/workflows/       # GitHub Actions workflows
├── .mise.toml               # Tool versions
├── Taskfile.yaml            # Task automation
└── go.mod                   # Go module definition
Available Tasks
task             # Show available tasks
task test        # Run all tests with coverage
task test:unit   # Run unit tests only
task lint        # Run all linters
task build       # Build binaries
task clean       # Clean build artifacts
Testing

All tests use Ginkgo/Gomega BDD framework:

# Run all tests
task test

# Run specific package
ginkgo -r pkg/commands/

# Watch mode for TDD
task test:watch

Current test coverage: 98 tests passing

  • 20 command parser tests
  • 12 CODEOWNERS parser tests
  • 30 permission checker tests
  • 30 feedback system tests
  • 18 GitHub client tests

Architecture

How It Works
  1. User comments /approve or /merge on a PR
  2. GitHub triggers issue_comment webhook
  3. pr-commands.yml workflow starts
  4. Action binary:
    • Parses the command
    • Reads .github/CODEOWNERS
    • Checks user permissions
    • Calls GitHub API
    • Posts reactions and feedback
Permission System

Phase 1 (Current):

  • Only global owners (* @username) are supported
  • Global owners can approve/merge any PR

Phase 2 (Planned):

  • Path-specific ownership patterns
  • Scoped permissions based on changed files
Security
  • All inputs passed via environment variables
  • No shell interpolation of user data
  • Actions pinned by commit digest
  • Minimal workflow permissions
  • Token-based authentication

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feat/amazing-feature)
  3. Write tests first (TDD)
  4. Implement the feature
  5. Ensure all checks pass: task lint && task test
  6. Commit with conventional commits (feat:, fix:, docs:, etc.)
  7. Push to your fork
  8. Open a pull request

Roadmap

Phase 1: GitHub Actions Bot ✅
  • Command parser
  • CODEOWNERS parser
  • Permission checker
  • GitHub API client
  • Feedback system
  • GitHub Actions workflows
  • Documentation
Phase 2: Enhanced Permissions (Planned)
  • Path-specific ownership
  • Scoped approval requirements
  • Team support in CODEOWNERS
  • Self-approval prevention
Phase 3: Kubernetes Deployment (Future)
  • HTTP webhook server
  • Persistent service
  • Scalable deployment
  • Prometheus metrics
Phase 4: Discord Integration (Future)
  • Discord bot
  • Unified command system
  • Cross-platform notifications

License

MIT License - see LICENSE for details

Acknowledgments

Built with:

  • Ginkgo - BDD testing framework
  • Gomega - Matcher library
  • mise - Tool version manager
  • Task - Task runner

Directories

Path Synopsis
cmd
github-action command
Package main provides the GitHub Actions entrypoint for Smyklot bot.
Package main provides the GitHub Actions entrypoint for Smyklot bot.
pkg
commands
Package commands provides command parsing for Smyklot PR comments
Package commands provides command parsing for Smyklot PR comments
config
Package config provides configuration management for Smyklot using Viper
Package config provides configuration management for Smyklot using Viper
feedback
Package feedback provides user-facing messages for Smyklot operations.
Package feedback provides user-facing messages for Smyklot operations.
github
Package github provides a GitHub API client for Smyklot operations.
Package github provides a GitHub API client for Smyklot operations.
permissions
Package permissions provides CODEOWNERS-based authorization for Smyklot.
Package permissions provides CODEOWNERS-based authorization for Smyklot.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL