Skip to main content
Version: 0.4.x

Introduction

The hack/config.yaml file in each plugin directory is a plugin-level tool configuration file used to declare custom steps that the plugin needs to execute during the build process. This configuration file primarily serves two scenarios:

  1. Custom build commands: Declare pre-compilation build steps via the build.commands field
  2. Code generation configuration: Configure database code generation parameters via the gfcli.gen field

This page focuses on custom build command configuration. For code generation configuration, refer to the GoFrame official documentation.

Configuration Hierarchy

LinaPro's configuration files exist at two levels, each with distinct responsibilities:

LevelFile PathPrimary Purpose
Repository-levelhack/config.yamlControls repository-wide compilation, image builds, and plugin source management
Plugin-levelapps/lina-plugins/<plugin-id>/hack/config.yamlControls code generation and custom build steps for a single plugin
info

The repository-level and plugin-level hack/config.yaml files share the same filename but serve entirely different purposes. Plugin-level configuration focuses on a single plugin's build needs and does not affect other plugins or the host framework.

Directory Structure

A typical plugin's hack/ directory looks like this:

apps/lina-plugins/<plugin-id>/
├── plugin.yaml
├── backend/
├── manifest/
├── frontend/
├── hack/
│ ├── config.yaml # Tool configuration file
│ └── tests/ # Test directory, optional
└── Makefile

Custom Build Configuration

Basic Syntax

Declare custom build steps in hack/config.yaml using the build.commands array:

build:
commands:
- "go generate ./..."
- "go-bindata -o assets.go -pkg assets ./static/..."

Each command executes sequentially in array order. If any command fails, the build process aborts and returns an error.

Available Variables

Build commands support variable expansion using the $(VARIABLE_NAME) syntax. Available variables include:

VariableDescriptionExample Value
$(PLUGIN_ROOT)Absolute path of the current plugin directory/path/to/apps/lina-plugins/linapro-ai-core
$(REPO_ROOT)Absolute path of the repository root/path/to/linapro

Example with variables:

build:
commands:
- "go -C $(REPO_ROOT) generate $(PLUGIN_ROOT)/backend/..."
- "protoc --go_out=$(PLUGIN_ROOT)/backend/internal $(PLUGIN_ROOT)/api/proto/*.proto"

Execution Environment

Custom build commands execute in the following environment:

  • Working directory: The current plugin directory ($(PLUGIN_ROOT))
  • Environment variables: Inherited from the host process
  • Execution timing: Runs before the host framework compilation

Complete Configuration Example

Here is a complete example that includes both custom build steps and code generation configuration:

# Custom build steps
build:
commands:
- "go generate ./..."
- "go-bindata -o internal/assets/assets.go -pkg assets ./static/..."

# GoFrame DAO code generation configuration
gfcli:
gen:
dao:
- link: "pgsql:postgres:postgres@tcp(127.0.0.1:5432)/linapro?sslmode=disable"
path: "internal"
tables: "plugin_linapro_demo_source_record"
removePrefix: "plugin_linapro_demo_source_"
importPrefix: "lina-plugin-linapro-demo-source/backend/internal"
descriptionTag: true
noModelComment: true
stdTime: true
typeMapping:
timestamp: {type: "*time.Time", import: time}
timestamptz: {type: "*time.Time", import: time}
date: {type: "*time.Time", import: time}
time: {type: "*time.Time", import: time}

Build Process

The plugin's custom build steps in the overall build process:

Relationship with Makefile

Each plugin directory has a Makefile for declaring plugin-level make targets, typically containing code generation commands:

PLUGIN_ROOT := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
REPO_ROOT := $(abspath $(PLUGIN_ROOT)/../../..)
include $(REPO_ROOT)/hack/makefiles/plugin.codegen.mk

The shared plugin.codegen.mk provides two common targets:

TargetDescription
make ctrlGenerate controller code
make daoGenerate database code (reads gfcli.gen.dao configuration from hack/config.yaml)
info

Makefile targets are for manual code generation during development, while build.commands in hack/config.yaml are for automatic execution during the build process. They complement each other without conflict.

Best Practices

  1. Keep commands simple: Each build command should focus on a single task for easier debugging and maintenance
  2. Use variable expansion: Avoid hardcoding paths; use $(PLUGIN_ROOT) and $(REPO_ROOT) for portability
  3. Handle dependencies: If commands have dependencies, ensure they are ordered correctly
  4. Add error handling: Build commands should return proper exit codes and abort the build on failure
  5. Document special commands: For complex build steps, explain their purpose in the plugin's README

Common Mistakes

MistakeCorrect Approach
Running time-consuming operations in build.commandsPlace time-consuming operations in development-time Makefile targets; only run essential steps during build
Hardcoding absolute pathsUse $(PLUGIN_ROOT) and $(REPO_ROOT) variables
Ignoring command execution orderBuild commands execute sequentially in array order; ensure dependency relationships are correct
Modifying host files in build.commandsCustom build steps should be confined to the plugin directory
Confusing repository-level and plugin-level configurationRepository-level controls the overall build; plugin-level controls a single plugin