diff --git a/README.md b/README.md index 523239d..cd88559 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,84 @@ -# go-ci +# Go CI/CD Composite Action +A reusable GitHub Action for Go projects, forged to handle various CI/CD scenarios like a true warrior of code. Supports protected branches, tagged releases, and minimal development flows β€” with optional Docker image publishing for applications. + +## πŸ”§ Features + +- Multiple workflow modes: `protected`, `tag`, and `minimal` +- Go version configuration +- Automatic test execution with code coverage +- Build support for both libraries and applications +- Conditional Docker image creation and publishing +- Composable and easy to integrate in any Go project + +## πŸ“₯ Inputs + +| Input Name | Description | Required | Default | +|---------------------|-------------------------------------------------------------------------|----------|---------------| +| `workflow-type` | Type of CI/CD flow (`protected`, `minimal`, `tag`) | Yes | `protected` | +| `go-version` | Go version to install and use | No | `1.24` | +| `build-type` | Type of build (`application`, `library`) | No | `application` | +| `container-registry`| Container registry URL (used if publishing Docker image) | Yes | β€” | +| `publish-docker` | Whether to build and push Docker image (`true` / `false`) | No | `true` | + +## βš™οΈ Workflow Types + +- **protected**: Full CI/CD pipeline for mainline branches. Runs tests, builds the binary, and optionally publishes a Docker image. +- **minimal**: Lean setup for pull requests or early development. Runs tests and builds only. +- **tag**: Triggered on Git tags. Behaves like `protected`, ideal for versioned releases. + +## πŸš€ How to Use + +```yaml +name: Go CI/CD Pipeline +on: [push, pull_request, workflow_dispatch] + +jobs: + go-ci: + runs-on: ubuntu-latest + steps: + - uses: your-org/go-ci-action@v1 + with: + workflow-type: 'protected' + go-version: '1.24' + build-type: 'application' + container-registry: ghcr.io/your-org + publish-docker: 'true' +``` + +> Replace your-org/go-ci-action and ghcr.io/your-org with your actual repository and registry. + +## πŸ› οΈ Step Breakdown + +1. **Checkout code** – Pulls the code from your repo. +2. **Set up Go** – Installs and configures the specified Go version. +3. **Download dependencies** – Runs `go mod tidy` to sync modules. +4. **Run tests** – Executes unit tests with JSON and coverage output. +5. **Build** – Builds all packages (`library`) or compiles an app binary (`application`). +6. **Generate image tag** – Creates a Docker tag based on branch/tag/ref. +7. **Login to registry** – Authenticates with your container registry. +8. **Build & push image** – Pushes the image if `publish-docker` is enabled. + +## πŸ” Requirements + +You must configure these in your environment for the action to work correctly: + +### Environment Variables + +- `DEPLOYER_USERNAME`: Your Docker registry username + +### Secrets + +- `DEPLOYER_TOKEN`: Your Docker registry password or access token + +## πŸ§™ Best Practices + +- Use `minimal` for development and PRs to save resources. +- Use `tag` for releases to generate versioned images. +- Disable `publish-docker` when working on Go libraries or services not meant to be containerized. + +--- + +Crafted with reusability, clarity, and precision in mind. May your builds be swift and your tests ever green. + +_β€œWe don’t just build software β€” we forge legacy.”_ \ No newline at end of file diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..b53b73e --- /dev/null +++ b/action.yml @@ -0,0 +1,102 @@ +name: 'Go CI/CD Pipeline' +description: 'Standardized workflow for Go projects (protected branches, tags, minimal CI)' + +inputs: + workflow-type: + description: 'Workflow type (protected, minimal, tag), default: protected' + required: true + default: 'protected' + go-version: + description: 'Go version' + required: false + default: '1.24' + build-type: + description: 'Build type (library/application), default: application' + required: false + default: 'application' + container-registry: + description: 'Container registry url' + required: true + publish-docker: + description: 'Publish Docker image (true/false)' + required: false + default: 'true' + +runs: + using: 'composite' + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup go + uses: actions/setup-go@v5 + with: + go-version: ${{ inputs.go-version }} + + - name: Download dependencies + shell: bash + run: | + go mod tidy -x + + - name: Run tests + shell: bash + run: | + go test -json > test-report.out + go test -coverprofile=coverage.out + + - name: Build library + if: inputs.build-type == 'library' + shell: bash + run: | + go build ./... + + - name: Build application + if: inputs.build-type == 'application' + shell: bash + run: | + go build -o ./bin/app main.go + + - name: Generate container image tag + if: inputs.publish-docker == 'true' && inputs.build-type == 'application' && (inputs.workflow-type == 'protected' || inputs.workflow-type == 'tag') + id: generate-tag + shell: bash + run: | + repository="${{ github.repository }}" + ref="${{ github.ref }}" + + if [[ "$ref" == "refs/heads/develop" ]]; then + tag="$(git rev-parse --short HEAD)" + elif [[ "$ref" == "refs/heads/main" ]]; then + tag="latest" + elif [[ "$ref" == refs/heads/release/* ]]; then + version="${ref#refs/heads/release/}" + tag="${version}-release" + elif [[ "$ref" == refs/tags/* ]]; then + tag="${ref#refs/tags/}" + else + echo "Unsupported ref: $ref" + exit 1 + fi + + echo "container-tag=${repository}:${tag}" >> $GITHUB_OUTPUT + + - name: Login to Registry + if: inputs.publish-docker == 'true' && inputs.build-type == 'application' && (inputs.workflow-type == 'protected' || inputs.workflow-type == 'tag') + uses: docker/login-action@v3 + with: + registry: ${{ inputs.container-registry }} + username: ${{ env.DEPLOYER_USERNAME }} + password: ${{ secrets.DEPLOYER_TOKEN }} + + - name: Set up Docker Buildx + if: inputs.publish-docker == 'true' && inputs.build-type == 'application' && (inputs.workflow-type == 'protected' || inputs.workflow-type == 'tag') + uses: docker/setup-buildx-action@v3 + + - name: Build and push container image + if: inputs.publish-docker == 'true' && inputs.build-type == 'application' && (inputs.workflow-type == 'protected' || inputs.workflow-type == 'tag') + uses: docker/build-push-action@v6 + with: + push: true + tags: "${{ inputs.container-registry }}/${{ steps.generate-tag.outputs.container-tag }}" \ No newline at end of file