Skip to content

Phase 4: Consolidate CI/CD workflows #4

@rianjs

Description

@rianjs

What

Create unified GitHub Actions workflows for the monorepo with path-based filtering to run only relevant jobs.

Workflows to Create

1. ci.yml - Unified CI

name: CI

on:
  push:
    branches: [main]
  pull_request:

jobs:
  detect-changes:
    runs-on: ubuntu-latest
    outputs:
      cfl: ${{ steps.filter.outputs.cfl }}
      jtk: ${{ steps.filter.outputs.jtk }}
      shared: ${{ steps.filter.outputs.shared }}
    steps:
      - uses: dorny/paths-filter@v3
        id: filter
        with:
          filters: |
            cfl:
              - 'tools/cfl/**'
              - 'shared/**'
            jtk:
              - 'tools/jtk/**'
              - 'shared/**'
            shared:
              - 'shared/**'

  test-cfl:
    needs: detect-changes
    if: needs.detect-changes.outputs.cfl == 'true'
    # ... build, test, lint for cfl

  test-jtk:
    needs: detect-changes
    if: needs.detect-changes.outputs.jtk == 'true'
    # ... build, test, lint for jtk

  test-shared:
    needs: detect-changes
    if: needs.detect-changes.outputs.shared == 'true'
    # ... test shared module

2. release-cfl.yml - Confluence CLI Release

Triggered by tags matching cfl-v*:

  • GoReleaser builds cfl binary
  • Publishes to GitHub Releases
  • Updates Homebrew tap
  • Updates Chocolatey package
  • Updates Winget manifest

3. release-jtk.yml - Jira CLI Release

Triggered by tags matching jtk-v*:

  • GoReleaser builds jtk binary
  • Publishes to GitHub Releases
  • Updates Homebrew tap
  • Updates Chocolatey package
  • Updates Winget manifest

GoReleaser Configs

Create tool-specific configs:

  • .goreleaser-cfl.yml - builds from tools/cfl/
  • .goreleaser-jtk.yml - builds from tools/jtk/

Key changes from original configs:

# .goreleaser-cfl.yml
builds:
  - id: cfl
    dir: tools/cfl
    main: ./cmd/cfl
    # ... rest same as before

Version Files

Maintain separate version tracking:

  • tools/cfl/version.txt0.9
  • tools/jtk/version.txt0.1

Auto-release workflow reads the appropriate version file based on which tool changed.

Why

Path filtering saves CI time and cost

Without path filters, every commit runs all jobs:

  • PR touching only tools/cfl/ runs jtk tests unnecessarily
  • Documentation changes trigger full build matrix
  • Wasted GitHub Actions minutes add up

With path filters:

  • Changes to tools/cfl/** only run cfl jobs
  • Changes to shared/** run both (it affects both tools)
  • Changes to README.md run nothing

Separate release tracks enable independent velocity

Tools can release at their own pace:

  • cfl is at v0.9.x, more mature, less frequent releases
  • jtk is at v0.1.x, actively developing, more frequent releases

Separate tags (cfl-v0.9.5, jtk-v0.1.12) mean:

  • Releasing cfl doesn't force a jtk release
  • Users can pin to specific tool versions
  • Changelogs are tool-specific

Consistent release process

Both tools use the same release machinery:

  • Same GoReleaser patterns
  • Same Homebrew tap
  • Same Chocolatey/Winget structure

Maintaining one pattern (with tool-specific configs) is easier than two divergent approaches.

Acceptance Criteria

  • .github/workflows/ci.yml exists with path filtering
  • .github/workflows/release-cfl.yml triggers on cfl-v* tags
  • .github/workflows/release-jtk.yml triggers on jtk-v* tags
  • .goreleaser-cfl.yml builds from tools/cfl/
  • .goreleaser-jtk.yml builds from tools/jtk/
  • PR touching only tools/cfl/ skips jtk jobs
  • PR touching shared/ runs both tool jobs
  • goreleaser release --config .goreleaser-cfl.yml --snapshot succeeds
  • goreleaser release --config .goreleaser-jtk.yml --snapshot succeeds

Dependencies

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions