diff --git a/README.md b/README.md index dbf1b181..25af844a 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,8 @@ The **OpenCHAMI cloud-init service** retrieves detailed inventory information fr - [Cluster Defaults and Instance Overrides](#cluster-defaults-and-instance-overrides) - [Set Cluster Defaults](#set-cluster-defaults) - [Override Instance Data](#override-instance-data) -6. [More Reading](#more-reading) +6. [CI/CD and Workflow Reuse](#cicd-and-workflow-reuse) +7. [More Reading](#more-reading) --- @@ -78,6 +79,54 @@ export BUILD_USER=$(whoami) --- +## CI/CD and Workflow Reuse + +This project uses a centralized, reusable GitHub Actions workflow for building and releasing Go applications. The workflow is defined in the [OpenCHAMI/github-actions](https://github.com/OpenCHAMI/github-actions) repository and can be used by other projects. + +### Using This Workflow in Your Project + +You can reuse the same release workflow in your own Go projects. The workflow provides: +- Multi-architecture builds (amd64, arm64) +- Container image creation and publishing +- Release artifact generation with GoReleaser +- Security scanning and build attestation + +**Quick example** for your own repository's `.github/workflows/Release.yml`: + +```yaml +name: Release + +on: + push: + tags: + - v* + +permissions: write-all + +jobs: + release: + uses: OpenCHAMI/github-actions/workflows/go-build-release.yml@v2 + with: + registry-name: ghcr.io/yourusername/yourproject +``` + +### Detailed Documentation + +For complete instructions, configuration options, and examples, see: +**[📖 Workflow Reuse Guide](docs/WORKFLOW_REUSE.md)** + +This guide covers: +- Configuration options and parameters +- GoReleaser setup requirements +- Container registry configuration +- Troubleshooting and debugging +- Security considerations + +**Quick start files:** +- [📋 Example Release Workflow](docs/example-release-workflow.yml) - Copy this to your project's `.github/workflows/Release.yml` + +--- + ## Running the Service ### Cluster Name @@ -226,7 +275,9 @@ curl -X PUT http://localhost:27777/cloud-init/admin/instance-info/x3000c1b1n1 \ ## More Reading +- [Workflow Reuse Guide](docs/WORKFLOW_REUSE.md) - How to use this project's CI/CD workflow in other repositories - [Official cloud-init documentation](https://cloud-init.io/) - [OpenCHAMI TPM-manager service](https://github.com/OpenCHAMI/TPM-manager) - [GoReleaser Documentation](https://goreleaser.com/) - [SMD Documentation](https://github.com/OpenCHAMI/smd) +- [OpenCHAMI GitHub Actions](https://github.com/OpenCHAMI/github-actions) - Centralized reusable workflows diff --git a/docs/WORKFLOW_REUSE.md b/docs/WORKFLOW_REUSE.md new file mode 100644 index 00000000..3357e665 --- /dev/null +++ b/docs/WORKFLOW_REUSE.md @@ -0,0 +1,252 @@ +# Reusing the OpenCHAMI Release Workflow + +This document explains how to use the centralized GitHub Actions workflow from the OpenCHAMI cloud-init repository in your own projects. + +## Overview + +The OpenCHAMI cloud-init project uses a centralized, reusable GitHub Actions workflow that handles: +- Go application building with GoReleaser +- Multi-architecture builds (amd64, arm64) +- Container image creation and publishing +- Release artifact generation +- Build attestation and security scanning + +The workflow is centralized in the [OpenCHAMI/github-actions](https://github.com/OpenCHAMI/github-actions) repository and can be reused by any Go project. + +## Quick Start + +To use this workflow in your own repository, create a `.github/workflows/Release.yml` file: + +```yaml +name: Release with goreleaser + +on: + workflow_dispatch: + push: + tags: + - v* + +permissions: write-all # Necessary for the generate-build-provenance action with containers + +jobs: + release: + uses: OpenCHAMI/github-actions/workflows/go-build-release.yml@v2 + with: + cgo-enabled: "1" + pre-build-commands: | + go install github.com/swaggo/swag/cmd/swag@latest + attestation-binary-path: "dist/cloud-init*" + registry-name: ghcr.io/openchami/cloud-init +``` + +> 💡 **Tip**: You can also copy the [example workflow file](example-release-workflow.yml) and customize it for your project. + +## Configuration Options + +The reusable workflow accepts several input parameters that you can customize: + +### Required Inputs + +- `registry-name`: The container registry where images will be pushed (e.g., `ghcr.io/yourusername/yourproject`) + +### Optional Inputs + +- `cgo-enabled`: Enable or disable CGO compilation (default: "0", set to "1" if needed) +- `pre-build-commands`: Commands to run before building (e.g., code generation, dependency installation) +- `attestation-binary-path`: Glob pattern for binaries to create attestations for +- `go-version`: Go version to use (defaults to latest stable) +- `goreleaser-version`: GoReleaser version to use (defaults to latest) + +## Usage Examples + +### Basic Go Application + +For a simple Go application without special requirements: + +```yaml +name: Release + +on: + push: + tags: + - v* + +permissions: write-all + +jobs: + release: + uses: OpenCHAMI/github-actions/workflows/go-build-release.yml@v2 + with: + registry-name: ghcr.io/myorg/myapp +``` + +### Application with Code Generation + +For applications that need code generation (like Swagger docs): + +```yaml +name: Release + +on: + push: + tags: + - v* + +permissions: write-all + +jobs: + release: + uses: OpenCHAMI/github-actions/workflows/go-build-release.yml@v2 + with: + cgo-enabled: "0" + pre-build-commands: | + go install github.com/swaggo/swag/cmd/swag@latest + swag init -g cmd/myapp/main.go + registry-name: ghcr.io/myorg/myapp + attestation-binary-path: "dist/myapp*" +``` + +### Application with CGO Dependencies + +For applications that require CGO (C bindings): + +```yaml +name: Release + +on: + push: + tags: + - v* + +permissions: write-all + +jobs: + release: + uses: OpenCHAMI/github-actions/workflows/go-build-release.yml@v2 + with: + cgo-enabled: "1" + registry-name: ghcr.io/myorg/myapp +``` + +## Prerequisites + +For the workflow to work properly in your repository, you need: + +### 1. GoReleaser Configuration + +Create a `.goreleaser.yaml` file in your repository root. You can use the [cloud-init example](./.goreleaser.yaml) as a template: + +```yaml +version: 2.4 +project_name: your-project-name + +before: + hooks: + - go mod tidy + # Add any additional pre-build commands here + +builds: + - id: your-app + main: ./cmd/your-app + binary: your-app + ldflags: + - "-X 'main.Version={{.Version}}' -X 'main.GitCommit={{.Commit}}'" + goos: + - linux + - darwin + goarch: + - amd64 + - arm64 + env: + - CGO_ENABLED=0 # or 1 if you need CGO + +# Add docker, archives, and other configurations as needed +``` + +### 2. Repository Permissions + +Ensure your repository has the necessary permissions: +- **Actions**: Enabled for running workflows +- **Packages**: Write permissions for container registry pushes +- **Contents**: Write permissions for creating releases + +### 3. Container Registry Setup + +If publishing to GitHub Container Registry (ghcr.io): +1. Enable the Package feature in your repository settings +2. Configure package visibility (public/private) +3. The workflow will automatically authenticate using the `GITHUB_TOKEN` + +## Environment Variables + +The workflow automatically sets these environment variables for GoReleaser: + +- `GIT_STATE`: "clean" or "dirty" based on repository state +- `BUILD_HOST`: Hostname of the build machine +- `GO_VERSION`: Go version being used +- `BUILD_USER`: Username performing the build + +You can reference these in your `.goreleaser.yaml` file: + +```yaml +builds: + - ldflags: + - "-X 'main.GitState={{ .Env.GIT_STATE }}'" + - "-X 'main.BuildHost={{ .Env.BUILD_HOST }}'" + - "-X 'main.GoVersion={{ .Env.GO_VERSION }}'" + - "-X 'main.BuildUser={{ .Env.BUILD_USER }}'" +``` + +## Triggering Releases + +The workflow is typically triggered by: + +1. **Tag pushes**: When you push a tag starting with 'v' + ```bash + git tag v1.0.0 + git push origin v1.0.0 + ``` + +2. **Manual dispatch**: Using the GitHub UI or CLI + ```bash + gh workflow run Release.yml + ``` + +## Troubleshooting + +### Common Issues + +1. **GoReleaser version mismatch**: Ensure your local GoReleaser version matches the one used in CI +2. **CGO errors**: Set `cgo-enabled: "1"` if your application uses C dependencies +3. **Permission errors**: Verify repository has write permissions for packages and contents +4. **Registry authentication**: Ensure container registry name matches your organization/username + +### Debugging + +To debug locally: + +1. Install GoReleaser locally +2. Set the required environment variables: + ```bash + export GIT_STATE=$(if git diff-index --quiet HEAD --; then echo 'clean'; else echo 'dirty'; fi) + export BUILD_HOST=$(hostname) + export GO_VERSION=$(go version | awk '{print $3}') + export BUILD_USER=$(whoami) + ``` +3. Run in snapshot mode: + ```bash + goreleaser release --snapshot --clean + ``` + +## Security Considerations + +The workflow includes security features: +- **Build attestation**: Creates signed attestations for build artifacts +- **Container scanning**: Automatically scans container images for vulnerabilities +- **Secure defaults**: Uses minimal permissions and secure build practices + +## More Information + +- [OpenCHAMI GitHub Actions Repository](https://github.com/OpenCHAMI/github-actions) +- [GoReleaser Documentation](https://goreleaser.com/) +- [GitHub Actions Reusable Workflows](https://docs.github.com/en/actions/using-workflows/reusing-workflows) \ No newline at end of file diff --git a/docs/example-release-workflow.yml b/docs/example-release-workflow.yml new file mode 100644 index 00000000..329d0cba --- /dev/null +++ b/docs/example-release-workflow.yml @@ -0,0 +1,41 @@ +# Example Release Workflow +# Copy this file to .github/workflows/Release.yml in your Go project +# to use the OpenCHAMI centralized release workflow + +name: Release with goreleaser + +on: + workflow_dispatch: + push: + tags: + - v* + +permissions: write-all # Necessary for the generate-build-provenance action with containers + +jobs: + release: + uses: OpenCHAMI/github-actions/workflows/go-build-release.yml@v2 + with: + # Configure these parameters for your project: + + # Registry where container images will be pushed + registry-name: ghcr.io/yourusername/yourproject + + # Enable CGO if your project has C dependencies (default: "0") + cgo-enabled: "0" + + # Commands to run before building (optional) + # Example: code generation, installing tools, etc. + pre-build-commands: | + echo "Add your pre-build commands here" + # go install github.com/swaggo/swag/cmd/swag@latest + # swag init -g cmd/yourapp/main.go + + # Pattern for binaries to create attestations for (optional) + attestation-binary-path: "dist/yourapp*" + +# Additional configuration notes: +# 1. Replace "yourusername/yourproject" with your actual registry path +# 2. Ensure you have a .goreleaser.yaml file in your repository root +# 3. Your repository needs write permissions for packages and contents +# 4. For private registries, you may need additional authentication setup \ No newline at end of file