├── .github ├── CODEOWNERS ├── dependabot.yml └── workflows │ ├── build.yml │ ├── coverage.yml │ ├── dependabot-sync.yml │ ├── goreleaser-deprecation-check.yml │ ├── goreleaser.yml │ ├── govulncheck.yml │ ├── lint-sync.yml │ ├── lint.yml │ ├── nightly.yml │ ├── pr-comment.yml │ ├── ruleguard.yml │ ├── semgrep.yml │ ├── snapshot.yml │ └── soft-serve.yml ├── .gitignore ├── LICENSE ├── README.md ├── dependabot ├── dependabot-bubbletea.yml ├── dependabot-colorprofile.yml ├── dependabot-huh.yml ├── dependabot-lipgloss.yml ├── dependabot-soft-serve-action.yml ├── dependabot-vhs-action.yml ├── dependabot-wish.yml ├── dependabot.yml ├── download-current.sh ├── run-workflow.sh └── workflows │ └── dependabot-sync.yml ├── footer.md ├── footer_lib.md ├── golangci.yml ├── goreleaser-announce.yaml ├── goreleaser-enterprise.yaml ├── goreleaser-full.yaml ├── goreleaser-glow.yaml ├── goreleaser-lib.yaml ├── goreleaser-mods.yaml ├── goreleaser-semi.yaml ├── goreleaser-sequin.yaml ├── goreleaser-simple.yaml ├── goreleaser-soft-serve.yaml ├── goreleaser-vhs.yaml ├── goreleaser.yaml ├── notarize.yaml ├── scripts └── run-lint-sync.sh └── templates └── README.md /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @caarlos0 @aymanbagabas 2 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | updates: 4 | - package-ecosystem: "gomod" 5 | directory: "/" 6 | schedule: 7 | interval: "weekly" 8 | day: "monday" 9 | time: "05:00" 10 | timezone: "America/New_York" 11 | labels: 12 | - "dependencies" 13 | commit-message: 14 | prefix: "chore" 15 | include: "scope" 16 | 17 | - package-ecosystem: "github-actions" 18 | directory: "/" 19 | schedule: 20 | interval: "weekly" 21 | day: "monday" 22 | time: "05:00" 23 | timezone: "America/New_York" 24 | labels: 25 | - "dependencies" 26 | commit-message: 27 | prefix: "chore" 28 | include: "scope" 29 | 30 | - package-ecosystem: "docker" 31 | directory: "/" 32 | schedule: 33 | interval: "weekly" 34 | day: "monday" 35 | time: "05:00" 36 | timezone: "America/New_York" 37 | labels: 38 | - "dependencies" 39 | commit-message: 40 | prefix: "chore" 41 | include: "scope" 42 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | go_version: 7 | required: false 8 | type: string 9 | go-version: 10 | required: false 11 | type: string 12 | default: stable 13 | go-version-file: 14 | required: false 15 | type: string 16 | working-directory: 17 | required: false 18 | type: string 19 | secrets: 20 | gh_pat: 21 | required: false 22 | 23 | jobs: 24 | govulncheck: 25 | runs-on: ubuntu-latest 26 | env: 27 | GH_PAT: ${{ secrets.gh_pat }} 28 | steps: 29 | - uses: actions/checkout@v4 30 | - uses: actions/setup-go@v5 31 | with: 32 | go-version: stable 33 | cache: true 34 | check-latest: true 35 | - run: | 36 | git config --global url."https://${{ secrets.gh_pat }}@github.com/charmbracelet".insteadOf "https://github.com/charmbracelet" 37 | git config --global url."https://${{ secrets.gh_pat }}@github.com/charmcli".insteadOf "https://github.com/charmcli" 38 | if: env.GH_PAT != null 39 | - run: go install golang.org/x/vuln/cmd/govulncheck@latest 40 | - run: go mod tidy 41 | - run: govulncheck ./... 42 | build: 43 | strategy: 44 | matrix: 45 | os: [ubuntu-latest, macos-latest, windows-latest] 46 | runs-on: ${{ matrix.os }} 47 | env: 48 | GO111MODULE: "on" 49 | GH_PAT: ${{ secrets.gh_pat }} 50 | steps: 51 | - name: Checkout code 52 | uses: actions/checkout@v4 53 | - run: | 54 | git config --global url."https://${{ secrets.gh_pat }}@github.com/charmbracelet".insteadOf "https://github.com/charmbracelet" 55 | git config --global url."https://${{ secrets.gh_pat }}@github.com/charmcli".insteadOf "https://github.com/charmcli" 56 | if: env.GH_PAT != null 57 | - name: Install Go 58 | uses: actions/setup-go@v5 59 | with: 60 | go-version: ${{ inputs.go_version || inputs.go-version }} 61 | go-version-file: ${{ inputs.go-version-file }} 62 | cache: true 63 | - name: Download Go modules 64 | run: go mod download 65 | working-directory: ${{ inputs.working-directory }} 66 | - name: Build 67 | run: go build ./... 68 | working-directory: ${{ inputs.working-directory }} 69 | - name: Test 70 | run: go test ./... 71 | working-directory: ${{ inputs.working-directory }} 72 | dependabot: 73 | needs: [build, govulncheck] 74 | runs-on: ubuntu-latest 75 | permissions: 76 | pull-requests: write 77 | contents: write 78 | if: ${{ github.actor == 'dependabot[bot]' && github.event_name == 'pull_request'}} 79 | steps: 80 | - id: metadata 81 | uses: dependabot/fetch-metadata@08eff52bf64351f401fb50d4972fa95b9f2c2d1b # v2.4.0 82 | with: 83 | github-token: "${{ secrets.GITHUB_TOKEN }}" 84 | - run: | 85 | gh pr review --approve "$PR_URL" 86 | gh pr merge --squash "$PR_URL" 87 | env: 88 | PR_URL: ${{github.event.pull_request.html_url}} 89 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 90 | -------------------------------------------------------------------------------- /.github/workflows/coverage.yml: -------------------------------------------------------------------------------- 1 | name: coverage 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | go-version: 7 | required: false 8 | type: string 9 | default: stable 10 | go-version-file: 11 | required: false 12 | type: string 13 | working-directory: 14 | required: false 15 | type: string 16 | test-timeout: 17 | required: false 18 | type: string 19 | default: 5m 20 | secrets: 21 | gh_pat: 22 | required: false 23 | codecov_token: 24 | required: false 25 | 26 | jobs: 27 | coverage: 28 | runs-on: ubuntu-latest 29 | env: 30 | GH_PAT: ${{ secrets.gh_pat }} 31 | steps: 32 | - name: Checkout code 33 | uses: actions/checkout@v4 34 | - run: | 35 | git config --global url."https://${{ secrets.gh_pat }}@github.com/charmbracelet".insteadOf "https://github.com/charmbracelet" 36 | git config --global url."https://${{ secrets.gh_pat }}@github.com/charmcli".insteadOf "https://github.com/charmcli" 37 | if: env.GH_PAT != null 38 | - name: Install Go 39 | uses: actions/setup-go@v5 40 | with: 41 | go-version: ${{ inputs.go-version }} 42 | go-version-file: ${{ inputs.go-version-file }} 43 | cache: true 44 | - name: Download Go modules 45 | run: go mod download 46 | working-directory: ${{ inputs.working-directory }} 47 | - name: Test 48 | run: go test -failfast -race -coverpkg=./... -covermode=atomic -coverprofile=coverage.txt ./... -timeout ${{ inputs.test-timeout }} 49 | working-directory: ${{ inputs.working-directory }} 50 | - uses: codecov/codecov-action@v5 51 | with: 52 | file: ./coverage.txt 53 | token: ${{ secrets.codecov_token }} 54 | working-directory: ${{ inputs.working-directory }} 55 | -------------------------------------------------------------------------------- /.github/workflows/dependabot-sync.yml: -------------------------------------------------------------------------------- 1 | name: dependabot-sync 2 | on: 3 | workflow_call: 4 | inputs: 5 | repo_name: 6 | description: The repository name, without the "charmbracelet/" prefix. 7 | required: true 8 | type: string 9 | secrets: 10 | gh_token: 11 | required: true 12 | workflow_dispatch: # allows manual triggering 13 | inputs: 14 | repo_name: 15 | description: The repository name, without the "charmbracelet/" prefix. 16 | required: true 17 | type: string 18 | 19 | permissions: 20 | contents: write 21 | pull-requests: write 22 | 23 | jobs: 24 | sync: 25 | runs-on: ubuntu-latest 26 | steps: 27 | - uses: actions/checkout@v4 28 | with: 29 | repository: ${{ github.repository_owner }}/${{ inputs.repo_name }} 30 | path: ${{ github.repository_owner }}/${{ inputs.repo_name }} 31 | token: ${{ secrets.gh_token || secrets.PERSONAL_ACCESS_TOKEN }} 32 | 33 | - uses: actions/checkout@v4 34 | with: 35 | repository: ${{ github.repository_owner }}/meta 36 | path: ${{ github.repository_owner }}/meta 37 | token: ${{ secrets.gh_token || secrets.PERSONAL_ACCESS_TOKEN }} 38 | 39 | - run: | 40 | mkdir -p "${{ github.repository_owner }}/${{ inputs.repo_name }}/.github/workflows" 41 | cp "${{ github.repository_owner }}/meta/dependabot/workflows/dependabot-sync.yml" "${{ github.repository_owner }}/${{ inputs.repo_name }}/.github/workflows/dependabot-sync.yml" 42 | cp "${{ github.repository_owner }}/meta/dependabot/dependabot.yml" "${{ github.repository_owner }}/${{ inputs.repo_name }}/.github/dependabot.yml" 43 | DEPENDABOT_FILE="${{ github.repository_owner }}/meta/dependabot/dependabot-${{ inputs.repo_name }}.yml" 44 | if [ -f "$DEPENDABOT_FILE" ]; then 45 | cat "$DEPENDABOT_FILE" >> "${{ github.repository_owner }}/${{ inputs.repo_name }}/.github/dependabot.yml" 46 | fi 47 | 48 | - name: Create Pull Request 49 | id: cpr 50 | uses: peter-evans/create-pull-request@v7 51 | with: 52 | commit-message: "ci: sync dependabot config" 53 | author: Charm <124303983+charmcli@users.noreply.github.com> 54 | title: "ci: sync dependabot config" 55 | body: | 56 | This is an automated pull request to sync the Dependabot config with the meta repository. 57 | branch: "ci/sync-dependabot-config" 58 | delete-branch: true 59 | path: "${{ github.repository_owner }}/${{ inputs.repo_name }}" 60 | token: ${{ secrets.gh_token || secrets.PERSONAL_ACCESS_TOKEN }} 61 | 62 | - name: Check outputs 63 | if: ${{ steps.cpr.outputs.pull-request-number }} 64 | run: | 65 | echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}" 66 | echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}" 67 | -------------------------------------------------------------------------------- /.github/workflows/goreleaser-deprecation-check.yml: -------------------------------------------------------------------------------- 1 | name: goreleaser-deprecation-check 2 | 3 | on: 4 | push: 5 | pull_request: 6 | 7 | jobs: 8 | check: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v4 12 | - uses: goreleaser/goreleaser-action@v6 13 | with: 14 | distribution: goreleaser-pro 15 | install-only: true 16 | - name: check 17 | run: | 18 | goreleaser check goreleaser*.yaml 19 | dependabot: 20 | needs: [check] 21 | runs-on: ubuntu-latest 22 | permissions: 23 | pull-requests: write 24 | contents: write 25 | if: ${{ github.actor == 'dependabot[bot]' && github.event_name == 'pull_request'}} 26 | steps: 27 | - id: metadata 28 | uses: dependabot/fetch-metadata@08eff52bf64351f401fb50d4972fa95b9f2c2d1b # v2.4.0 29 | with: 30 | github-token: "${{ secrets.GITHUB_TOKEN }}" 31 | - run: | 32 | gh pr review --approve "$PR_URL" 33 | gh pr merge --squash "$PR_URL" 34 | env: 35 | PR_URL: ${{github.event.pull_request.html_url}} 36 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 37 | -------------------------------------------------------------------------------- /.github/workflows/goreleaser.yml: -------------------------------------------------------------------------------- 1 | name: goreleaser 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | go_version: 7 | required: false 8 | type: string 9 | default: stable 10 | upload_artifact: 11 | required: false 12 | type: boolean 13 | default: true 14 | lfs: 15 | required: false 16 | type: boolean 17 | default: false 18 | description: Whether to download Git-LFS files 19 | macos_sign_entitlements: 20 | required: false 21 | type: string 22 | description: Path to entitlements file 23 | secrets: 24 | docker_username: 25 | required: true 26 | docker_token: 27 | required: true 28 | gh_pat: 29 | required: true 30 | goreleaser_key: 31 | required: true 32 | aur_key: 33 | required: false 34 | fury_token: 35 | required: false 36 | nfpm_gpg_key: 37 | required: false 38 | nfpm_passphrase: 39 | required: false 40 | snapcraft_token: 41 | required: false 42 | twitter_consumer_key: 43 | required: false 44 | twitter_consumer_secret: 45 | required: false 46 | twitter_access_token: 47 | required: false 48 | twitter_access_token_secret: 49 | required: false 50 | mastodon_client_id: 51 | required: false 52 | mastodon_client_secret: 53 | required: false 54 | mastodon_access_token: 55 | required: false 56 | discord_webhook_id: 57 | required: false 58 | discord_webhook_token: 59 | required: false 60 | macos_sign_p12: 61 | required: false 62 | macos_sign_password: 63 | required: false 64 | macos_notary_key: 65 | required: false 66 | macos_notary_key_id: 67 | required: false 68 | macos_notary_issuer_id: 69 | required: false 70 | 71 | jobs: 72 | release: 73 | runs-on: ubuntu-latest 74 | permissions: 75 | contents: write 76 | id-token: write 77 | packages: write 78 | env: 79 | DOCKER_CLI_EXPERIMENTAL: enabled 80 | steps: 81 | - uses: actions/checkout@v4 82 | with: 83 | fetch-depth: 0 84 | lfs: ${{ inputs.lfs }} 85 | - run: | 86 | git config --global url."https://${{ secrets.gh_pat }}@github.com/charmbracelet".insteadOf "https://github.com/charmbracelet" 87 | git config --global url."https://${{ secrets.gh_pat }}@github.com/charmcli".insteadOf "https://github.com/charmcli" 88 | - uses: actions/setup-go@v5 89 | with: 90 | go-version: ${{ inputs.go_version }} 91 | cache: true 92 | check-latest: true 93 | - uses: sigstore/cosign-installer@v3.8.2 94 | - uses: cachix/install-nix-action@v31 95 | with: 96 | github_access_token: ${{ secrets.gh_pat }} 97 | - uses: anchore/sbom-action/download-syft@v0.20.0 98 | - uses: docker/setup-qemu-action@v3 99 | - uses: docker/setup-buildx-action@v3 100 | - uses: docker/login-action@v3 101 | name: ghcr.io login 102 | with: 103 | registry: ghcr.io 104 | username: ${{ github.repository_owner }} 105 | password: ${{ secrets.GITHUB_TOKEN }} 106 | - uses: docker/login-action@v3 107 | name: docker.io login 108 | with: 109 | username: ${{ secrets.docker_username }} 110 | password: ${{ secrets.docker_token }} 111 | - run: | 112 | echo "$NFPM_GPG_KEY" > ${{ runner.temp }}/gpg.key 113 | env: 114 | NFPM_GPG_KEY: ${{ secrets.nfpm_gpg_key }} 115 | - uses: samuelmeuli/action-snapcraft@v3 116 | - uses: goreleaser/goreleaser-action@v6 117 | with: 118 | version: latest 119 | distribution: goreleaser-pro 120 | args: release --clean 121 | env: 122 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 123 | HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.gh_pat }} 124 | GORELEASER_KEY: ${{ secrets.goreleaser_key }} 125 | AUR_KEY: ${{ secrets.aur_key }} 126 | FURY_TOKEN: ${{ secrets.fury_token }} 127 | GPG_KEY_PATH: ${{ runner.temp }}/gpg.key 128 | NFPM_DEFAULT_PASSPHRASE: ${{ secrets.nfpm_passphrase }} 129 | TWITTER_CONSUMER_KEY: ${{ secrets.twitter_consumer_key }} 130 | TWITTER_CONSUMER_SECRET: ${{ secrets.twitter_consumer_secret }} 131 | TWITTER_ACCESS_TOKEN: ${{ secrets.twitter_access_token }} 132 | TWITTER_ACCESS_TOKEN_SECRET: ${{ secrets.twitter_access_token_secret }} 133 | MASTODON_CLIENT_ID: ${{ secrets.mastodon_client_id }} 134 | MASTODON_CLIENT_SECRET: ${{ secrets.mastodon_client_secret }} 135 | MASTODON_ACCESS_TOKEN: ${{ secrets.mastodon_access_token }} 136 | DISCORD_WEBHOOK_ID: ${{ secrets.discord_webhook_id }} 137 | DISCORD_WEBHOOK_TOKEN: ${{ secrets.discord_webhook_token }} 138 | MACOS_SIGN_P12: ${{ secrets.macos_sign_p12 }} 139 | MACOS_SIGN_PASSWORD: ${{ secrets.macos_sign_password }} 140 | MACOS_SIGN_ENTITLEMENTS: ${{ inputs.macos_sign_entitlements }} 141 | MACOS_NOTARY_ISSUER_ID: ${{ secrets.macos_notary_issuer_id }} 142 | MACOS_NOTARY_KEY_ID: ${{ secrets.macos_notary_key_id }} 143 | MACOS_NOTARY_KEY: ${{ secrets.macos_notary_key }} 144 | SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.snapcraft_token }} 145 | 146 | - uses: actions/upload-artifact@v4 147 | if: ${{ inputs.upload_artifact == true && always() }} 148 | with: 149 | retention-days: 30 150 | name: dist 151 | path: | 152 | dist 153 | 154 | # yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json 155 | -------------------------------------------------------------------------------- /.github/workflows/govulncheck.yml: -------------------------------------------------------------------------------- 1 | name: govulncheck 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | go-version: 7 | required: false 8 | type: string 9 | default: stable 10 | cache: 11 | required: false 12 | type: boolean 13 | default: true 14 | run: 15 | required: false 16 | type: string 17 | secrets: 18 | gh_pat: 19 | required: false 20 | 21 | permissions: 22 | contents: read 23 | 24 | jobs: 25 | scan: 26 | runs-on: ubuntu-latest 27 | env: 28 | GH_PAT: ${{ secrets.gh_pat }} 29 | RUN: ${{ inputs.run }} 30 | steps: 31 | - run: | 32 | git config --global url."https://${{ secrets.gh_pat }}@github.com/charmbracelet".insteadOf "https://github.com/charmbracelet" 33 | git config --global url."https://${{ secrets.gh_pat }}@github.com/charmcli".insteadOf "https://github.com/charmcli" 34 | if: env.GH_PAT != null 35 | - uses: actions/checkout@v4 36 | - uses: actions/setup-go@v5 37 | with: 38 | go-version: ${{ inputs.go-version }} 39 | cache: ${{ inputs.cache }} 40 | - run: ${{ inputs.run }} 41 | if: env.RUN != null 42 | - name: govulncheck 43 | run: | 44 | go install golang.org/x/vuln/cmd/govulncheck@latest 45 | govulncheck ./... 46 | -------------------------------------------------------------------------------- /.github/workflows/lint-sync.yml: -------------------------------------------------------------------------------- 1 | name: lint-sync 2 | on: 3 | workflow_call: 4 | 5 | permissions: 6 | contents: write 7 | pull-requests: write 8 | 9 | jobs: 10 | sync: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | with: 15 | path: ${{ github.repository }} 16 | - uses: actions/checkout@v4 17 | with: 18 | repository: ${{ github.repository_owner }}/meta 19 | path: ${{ github.repository_owner }}/meta 20 | - run: | 21 | cp ${{ github.repository_owner }}/meta/golangci.yml ${{ github.repository }}/.golangci.yml 22 | rm -rf ${{ github.repository }}/.golangci-soft.yml 23 | - name: Create Pull Request 24 | id: cpr 25 | uses: peter-evans/create-pull-request@v7 26 | with: 27 | commit-message: "ci: sync golangci-lint config" 28 | title: "ci: sync golangci-lint config" 29 | body: | 30 | This is an automated pull request to sync the golangci-lint config with the meta repository. 31 | branch: "ci/sync-lint-config" 32 | delete-branch: true 33 | path: "${{ github.repository }}" 34 | - name: Check outputs 35 | if: ${{ steps.cpr.outputs.pull-request-number }} 36 | run: | 37 | echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}" 38 | echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}" 39 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: lint 2 | on: 3 | workflow_call: 4 | inputs: 5 | directory: 6 | type: string 7 | required: false 8 | default: "" 9 | description: Path to the directory to run golangci-lint in. 10 | golangci_path: 11 | type: string 12 | required: false 13 | description: Path to golangci.yml 14 | 15 | permissions: 16 | # Required: allow read access to the content for analysis. 17 | contents: read 18 | # Optional: allow read access to pull request. Use with `only-new-issues` option. 19 | pull-requests: read 20 | # Optional: allow write access to checks to allow the action to annotate code in the PR. 21 | checks: write 22 | 23 | jobs: 24 | lint: 25 | strategy: 26 | matrix: 27 | os: [ubuntu-latest, macos-latest, windows-latest] 28 | runs-on: ${{ matrix.os }} 29 | steps: 30 | # By default, the GitHub Action on Windows uses `core.autocrlf=true`. 31 | # LF is converted to CRLF, this produces reports from formatters (gofmt/gofumpt/etc.). 32 | - run: "git config --global core.autocrlf input" 33 | - uses: actions/checkout@v4 34 | with: 35 | path: ${{ github.repository }} 36 | - uses: actions/checkout@v4 37 | with: 38 | repository: ${{ github.repository_owner }}/meta 39 | path: ${{ github.repository_owner }}/meta 40 | - name: Install Go 41 | uses: actions/setup-go@v5 42 | with: 43 | go-version: stable 44 | - name: golangci-lint 45 | uses: golangci/golangci-lint-action@v8 46 | with: 47 | working-directory: ${{ github.repository }} 48 | args: | 49 | --config="${{ inputs.golangci_path || format('{0}/{1}/meta/golangci.yml', github.workspace, github.repository_owner) }}" --timeout=5m ${{ inputs.directory }} 50 | -------------------------------------------------------------------------------- /.github/workflows/nightly.yml: -------------------------------------------------------------------------------- 1 | name: nightly 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | upload_artifacts: 7 | required: false 8 | type: boolean 9 | default: true 10 | upload_artifact: 11 | required: false 12 | type: boolean 13 | default: true 14 | go_version: 15 | required: false 16 | type: string 17 | default: stable 18 | lfs: 19 | required: false 20 | type: boolean 21 | default: false 22 | description: Whether to download Git-LFS files 23 | secrets: 24 | docker_username: 25 | required: true 26 | docker_token: 27 | required: true 28 | goreleaser_key: 29 | required: true 30 | gh_pat: 31 | required: false 32 | fury_token: 33 | required: false 34 | macos_sign_p12: 35 | required: false 36 | macos_sign_password: 37 | required: false 38 | macos_notary_key: 39 | required: false 40 | macos_notary_key_id: 41 | required: false 42 | macos_notary_issuer_id: 43 | required: false 44 | 45 | jobs: 46 | nightly: 47 | runs-on: ubuntu-latest 48 | # dependabot-created PRs cant see any secrets, so this workflow wont work anyway https://github.com/dependabot/dependabot-core/issues/3253 49 | if: ${{ github.actor != 'dependabot[bot]' }} 50 | permissions: 51 | contents: write 52 | id-token: write 53 | packages: write 54 | env: 55 | DOCKER_CLI_EXPERIMENTAL: enabled 56 | GH_PAT: ${{ secrets.gh_pat }} 57 | steps: 58 | - uses: actions/checkout@v4 59 | with: 60 | fetch-depth: 0 61 | lfs: ${{ inputs.lfs }} 62 | - run: | 63 | git config --global url."https://${{ secrets.gh_pat }}@github.com/charmbracelet".insteadOf "https://github.com/charmbracelet" 64 | git config --global url."https://${{ secrets.gh_pat }}@github.com/charmcli".insteadOf "https://github.com/charmcli" 65 | if: env.GH_PAT != null 66 | - uses: actions/setup-go@v5 67 | with: 68 | go-version: ${{ inputs.go_version }} 69 | cache: true 70 | check-latest: true 71 | - uses: sigstore/cosign-installer@v3.8.2 72 | - uses: anchore/sbom-action/download-syft@v0.20.0 73 | - uses: docker/setup-qemu-action@v3 74 | - uses: docker/setup-buildx-action@v3 75 | - uses: docker/login-action@v3 76 | name: ghcr.io login 77 | with: 78 | registry: ghcr.io 79 | username: ${{ github.repository_owner }} 80 | password: ${{ secrets.GITHUB_TOKEN }} 81 | - uses: docker/login-action@v3 82 | name: docker.io login 83 | with: 84 | username: ${{ secrets.docker_username }} 85 | password: ${{ secrets.docker_token }} 86 | - uses: goreleaser/goreleaser-action@v6 87 | with: 88 | version: latest 89 | distribution: goreleaser-pro 90 | args: release --clean --nightly 91 | env: 92 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 93 | GORELEASER_KEY: ${{ secrets.goreleaser_key }} 94 | FURY_TOKEN: ${{ secrets.fury_token }} 95 | MACOS_SIGN_P12: ${{ secrets.macos_sign_p12 }} 96 | MACOS_SIGN_PASSWORD: ${{ secrets.macos_sign_password }} 97 | MACOS_NOTARY_ISSUER_ID: ${{ secrets.macos_notary_issuer_id }} 98 | MACOS_NOTARY_KEY_ID: ${{ secrets.macos_notary_key_id }} 99 | MACOS_NOTARY_KEY: ${{ secrets.macos_notary_key }} 100 | - uses: actions/upload-artifact@v4 101 | if: ${{ inputs.upload_artifact == true && always() }} 102 | with: 103 | retention-days: 30 104 | name: dist 105 | path: | 106 | dist 107 | -------------------------------------------------------------------------------- /.github/workflows/pr-comment.yml: -------------------------------------------------------------------------------- 1 | name: pr-comment 2 | 3 | on: 4 | workflow_call: 5 | 6 | jobs: 7 | pr-comment: 8 | if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/github-script@v7 12 | with: 13 | # This snippet is public-domain, taken from 14 | # https://github.com/oprypin/nightly.link/blob/master/.github/workflows/pr-comment.yml 15 | script: | 16 | async function upsertComment(owner, repo, issue_number, purpose, body) { 17 | const {data: comments} = await github.rest.issues.listComments( 18 | {owner, repo, issue_number}); 19 | 20 | const marker = ``; 21 | body = marker + "\n" + body; 22 | 23 | const existing = comments.filter((c) => c.body.includes(marker)); 24 | if (existing.length > 0) { 25 | const last = existing[existing.length - 1]; 26 | core.info(`Updating comment ${last.id}`); 27 | await github.rest.issues.updateComment({ 28 | owner, repo, 29 | body, 30 | comment_id: last.id, 31 | }); 32 | } else { 33 | core.info(`Creating a comment in issue / PR #${issue_number}`); 34 | await github.rest.issues.createComment({issue_number, body, owner, repo}); 35 | } 36 | } 37 | 38 | const {owner, repo} = context.repo; 39 | const run_id = ${{github.event.workflow_run.id}}; 40 | 41 | const pull_requests = ${{ toJSON(github.event.workflow_run.pull_requests) }}; 42 | if (!pull_requests.length) { 43 | return core.error("This workflow doesn't match any pull requests!"); 44 | } 45 | 46 | const artifacts = await github.paginate( 47 | github.rest.actions.listWorkflowRunArtifacts, {owner, repo, run_id}); 48 | if (!artifacts.length) { 49 | return core.error(`No artifacts found`); 50 | } 51 | const sha = "${{github.event.workflow_run.head_sha}}"; 52 | let body = `Download the artifacts for this pull request:\n`; 53 | for (const art of artifacts) { 54 | body += `\n* [${art.name}.zip](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`; 55 | } 56 | body += `\n\nOr use the following Docker image \`ghcr.io/${owner}/${repo}:devel-${sha.substr(0,7)}\``; 57 | 58 | core.info("Review thread message body:", body); 59 | 60 | for (const pr of pull_requests) { 61 | await upsertComment(owner, repo, pr.number, "nightly-link", body); 62 | } 63 | -------------------------------------------------------------------------------- /.github/workflows/ruleguard.yml: -------------------------------------------------------------------------------- 1 | name: ruleguard 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | go-version: 7 | required: false 8 | type: string 9 | default: stable 10 | cache: 11 | required: false 12 | type: boolean 13 | default: true 14 | args: 15 | required: false 16 | type: string 17 | default: "" 18 | run: 19 | required: false 20 | type: string 21 | secrets: 22 | gh_pat: 23 | required: false 24 | 25 | permissions: 26 | contents: read 27 | 28 | jobs: 29 | scan: 30 | runs-on: ubuntu-latest 31 | env: 32 | GH_PAT: ${{ secrets.gh_pat }} 33 | RUN: ${{ inputs.run }} 34 | steps: 35 | - run: | 36 | git config --global url."https://${{ secrets.gh_pat }}@github.com/charmbracelet".insteadOf "https://github.com/charmbracelet" 37 | git config --global url."https://${{ secrets.gh_pat }}@github.com/charmcli".insteadOf "https://github.com/charmcli" 38 | if: env.GH_PAT != null 39 | - uses: actions/checkout@v4 40 | - uses: actions/checkout@v4 41 | with: 42 | repository: dgryski/semgrep-go 43 | path: rules 44 | - uses: actions/setup-go@v5 45 | with: 46 | go-version: ${{ inputs.go-version }} 47 | cache: ${{ inputs.cache }} 48 | - run: ${{ inputs.run }} 49 | if: env.RUN != null 50 | - name: ruleguard 51 | run: | 52 | # needs to be outside of the workspace for some reason 53 | mv rules ../ 54 | go install github.com/quasilyte/go-ruleguard/cmd/ruleguard@latest 55 | go get -u github.com/quasilyte/go-ruleguard/dsl@latest 56 | ruleguard -c=0 -rules ../rules/ruleguard.rules.go ${{ inputs.args }} ./... 57 | -------------------------------------------------------------------------------- /.github/workflows/semgrep.yml: -------------------------------------------------------------------------------- 1 | name: semgrep 2 | 3 | on: 4 | workflow_call: 5 | secrets: 6 | gh_pat: 7 | required: false 8 | 9 | permissions: 10 | contents: read 11 | 12 | jobs: 13 | scan: 14 | runs-on: ubuntu-latest 15 | container: 16 | image: returntocorp/semgrep 17 | env: 18 | GH_PAT: ${{ secrets.gh_pat }} 19 | steps: 20 | - run: | 21 | git config --global url."https://${{ secrets.gh_pat }}@github.com/charmbracelet".insteadOf "https://github.com/charmbracelet" 22 | git config --global url."https://${{ secrets.gh_pat }}@github.com/charmcli".insteadOf "https://github.com/charmcli" 23 | if: env.GH_PAT != null 24 | - uses: actions/checkout@v4 25 | - uses: actions/checkout@v4 26 | with: 27 | repository: dgryski/semgrep-go 28 | path: rules 29 | - name: semgrep 30 | run: semgrep scan --error --enable-nosem -f ./rules . 31 | -------------------------------------------------------------------------------- /.github/workflows/snapshot.yml: -------------------------------------------------------------------------------- 1 | name: snapshot 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | go_version: 7 | required: false 8 | type: string 9 | default: ^1 10 | upload_artifact: 11 | required: false 12 | type: boolean 13 | default: true 14 | secrets: 15 | goreleaser_key: 16 | required: true 17 | gh_pat: 18 | required: false 19 | 20 | jobs: 21 | snapshot: 22 | runs-on: ubuntu-latest 23 | permissions: 24 | contents: read 25 | env: 26 | DOCKER_CLI_EXPERIMENTAL: enabled 27 | GH_PAT: ${{ secrets.gh_pat }} 28 | steps: 29 | - uses: actions/checkout@v4 30 | with: 31 | fetch-depth: 0 32 | - run: | 33 | git config --global url."https://${{ secrets.gh_pat }}@github.com/charmbracelet".insteadOf "https://github.com/charmbracelet" 34 | git config --global url."https://${{ secrets.gh_pat }}@github.com/charmcli".insteadOf "https://github.com/charmcli" 35 | if: env.GH_PAT != null 36 | - uses: actions/setup-go@v5 37 | with: 38 | go-version: ${{ inputs.go_version }} 39 | cache: true 40 | check-latest: true 41 | - uses: docker/setup-qemu-action@v3 42 | - uses: docker/setup-buildx-action@v3 43 | - run: sudo snap install snapcraft --classic 44 | - uses: goreleaser/goreleaser-action@v6 45 | with: 46 | version: latest 47 | distribution: goreleaser-pro 48 | args: release --clean --snapshot --skip=sign,sbom 49 | env: 50 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 51 | - uses: actions/upload-artifact@v4 52 | if: ${{ inputs.upload_artifact == true && always() }} 53 | with: 54 | retention-days: 7 55 | name: dist 56 | path: | 57 | dist 58 | -------------------------------------------------------------------------------- /.github/workflows/soft-serve.yml: -------------------------------------------------------------------------------- 1 | name: soft-serve 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | server: 7 | type: string 8 | default: "git.charm.sh" 9 | required: false 10 | secrets: 11 | ssh-key: 12 | required: true 13 | 14 | jobs: 15 | soft-serve: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v4 19 | with: 20 | fetch-depth: 0 21 | - name: Push to Soft-Serve 22 | uses: charmbracelet/soft-serve-action@master 23 | with: 24 | server: "${{ inputs.server }}" 25 | ssh-key: "${{ secrets.ssh-key }}" 26 | mirror: "true" 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | dependabot/current 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022-2023 Charmbracelet, Inc 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # meta 2 | 3 | This repo contains Charm’s meta configuration files: 4 | 5 | - GoReleaser configurations 6 | - GitHub Actions workflows 7 | 8 | ## Related docs 9 | 10 | - [GitHub: Reusing Workflows](https://docs.github.com/en/actions/learn-github-actions/reusing-workflows) 11 | - [GoReleaser: includes](https://goreleaser.com/customization/includes/) 12 | 13 | ## Usage 14 | 15 | ### GoReleaser release 16 | 17 | ```yaml 18 | # .goreleaser.yml 19 | includes: 20 | - from_url: 21 | url: charmbracelet/meta/main/goreleaser.yaml 22 | 23 | variables: 24 | main: "" 25 | binary_name: "" 26 | description: "" 27 | github_url: "" 28 | maintainer: "" 29 | homepage: "https://charm.sh/" 30 | brew_commit_author_name: "" 31 | brew_commit_author_email: "" 32 | brew_owner: charmbracelet 33 | docker_io_registry_owner: charmcli 34 | ghcr_io_registry_owner: charmbracelet 35 | ``` 36 | 37 | > You can override the variables you need 38 | 39 | ```yaml 40 | # .github/workflows/goreleaser.yml 41 | name: goreleaser 42 | 43 | on: 44 | push: 45 | tags: 46 | - v*.*.* 47 | 48 | concurrency: 49 | group: goreleaser 50 | cancel-in-progress: true 51 | 52 | jobs: 53 | goreleaser: 54 | uses: charmbracelet/meta/.github/workflows/goreleaser.yml@main 55 | secrets: 56 | docker_username: ${{ secrets.DOCKERHUB_USERNAME }} 57 | docker_token: ${{ secrets.DOCKERHUB_TOKEN }} 58 | gh_pat: ${{ secrets.PERSONAL_ACCESS_TOKEN }} 59 | goreleaser_key: ${{ secrets.GORELEASER_KEY } 60 | ``` 61 | 62 | You'll need to set the secrets used. 63 | 64 | ### GoReleaser snapshot 65 | 66 | ```yaml 67 | # .github/workflows/snapshot.yml 68 | name: snapshot 69 | 70 | on: [push, pull_request] 71 | 72 | jobs: 73 | snapshot: 74 | uses: charmbracelet/meta/.github/workflows/snapshot.yml@main 75 | secrets: 76 | goreleaser_key: ${{ secrets.GORELEASER_KEY }} 77 | ``` 78 | 79 | ### GoReleaser nightly 80 | 81 | ```yaml 82 | # .github/workflows/nightly.yml 83 | name: nightly 84 | 85 | on: push 86 | 87 | jobs: 88 | nightly: 89 | uses: charmbracelet/meta/.github/workflows/nightly.yml@main 90 | secrets: 91 | docker_username: ${{ secrets.DOCKERHUB_USERNAME }} 92 | docker_token: ${{ secrets.DOCKER_PASSWORD }} 93 | goreleaser_key: ${{ secrets.GORELEASER_KEY }} 94 | ``` 95 | 96 | ```yaml 97 | # .github/workflows/pr-comment.yml 98 | name: pr-comment 99 | 100 | on: 101 | workflow_run: 102 | workflows: [build] 103 | types: [completed] 104 | 105 | jobs: 106 | pr-comment: 107 | uses: charmbracelet/meta/.github/workflows/pr-comment.yml@main 108 | ``` 109 | 110 | --- 111 | 112 | Part of [Charm](https://charm.sh). 113 | 114 | The Charm logo 115 | 116 | 117 | Charm热爱开源 • Charm loves open source 118 | -------------------------------------------------------------------------------- /dependabot/dependabot-bubbletea.yml: -------------------------------------------------------------------------------- 1 | 2 | - package-ecosystem: "gomod" 3 | directory: "/examples" 4 | schedule: 5 | interval: "weekly" 6 | day: "monday" 7 | time: "05:00" 8 | timezone: "America/New_York" 9 | labels: 10 | - "dependencies" 11 | commit-message: 12 | prefix: "chore" 13 | include: "scope" 14 | 15 | - package-ecosystem: "gomod" 16 | directory: "/tutorials" 17 | schedule: 18 | interval: "weekly" 19 | day: "monday" 20 | time: "05:00" 21 | timezone: "America/New_York" 22 | labels: 23 | - "dependencies" 24 | commit-message: 25 | prefix: "chore" 26 | include: "scope" 27 | -------------------------------------------------------------------------------- /dependabot/dependabot-colorprofile.yml: -------------------------------------------------------------------------------- 1 | 2 | - package-ecosystem: "gomod" 3 | directory: "/examples" 4 | schedule: 5 | interval: "weekly" 6 | day: "monday" 7 | time: "05:00" 8 | timezone: "America/New_York" 9 | labels: 10 | - "dependencies" 11 | commit-message: 12 | prefix: "chore" 13 | include: "scope" 14 | 15 | - package-ecosystem: "gomod" 16 | directory: "/tutorials" 17 | schedule: 18 | interval: "weekly" 19 | day: "monday" 20 | time: "05:00" 21 | timezone: "America/New_York" 22 | labels: 23 | - "dependencies" 24 | commit-message: 25 | prefix: "chore" 26 | include: "scope" 27 | -------------------------------------------------------------------------------- /dependabot/dependabot-huh.yml: -------------------------------------------------------------------------------- 1 | 2 | - package-ecosystem: "gomod" 3 | directory: "/examples" 4 | schedule: 5 | interval: "weekly" 6 | day: "monday" 7 | time: "05:00" 8 | timezone: "America/New_York" 9 | labels: 10 | - "dependencies" 11 | commit-message: 12 | prefix: "chore" 13 | include: "scope" 14 | 15 | - package-ecosystem: "gomod" 16 | directory: "/spinner" 17 | schedule: 18 | interval: "weekly" 19 | day: "monday" 20 | time: "05:00" 21 | timezone: "America/New_York" 22 | labels: 23 | - "dependencies" 24 | commit-message: 25 | prefix: "chore" 26 | include: "scope" 27 | -------------------------------------------------------------------------------- /dependabot/dependabot-lipgloss.yml: -------------------------------------------------------------------------------- 1 | 2 | - package-ecosystem: "gomod" 3 | directory: "/example" 4 | schedule: 5 | interval: "weekly" 6 | day: "monday" 7 | time: "05:00" 8 | timezone: "America/New_York" 9 | labels: 10 | - "dependencies" 11 | commit-message: 12 | prefix: "chore" 13 | include: "scope" 14 | -------------------------------------------------------------------------------- /dependabot/dependabot-soft-serve-action.yml: -------------------------------------------------------------------------------- 1 | 2 | - package-ecosystem: npm 3 | directory: / 4 | schedule: 5 | interval: "weekly" 6 | day: "monday" 7 | time: "05:00" 8 | timezone: "America/New_York" 9 | -------------------------------------------------------------------------------- /dependabot/dependabot-vhs-action.yml: -------------------------------------------------------------------------------- 1 | 2 | - package-ecosystem: npm 3 | directory: / 4 | schedule: 5 | interval: "weekly" 6 | day: "monday" 7 | time: "05:00" 8 | timezone: "America/New_York" 9 | -------------------------------------------------------------------------------- /dependabot/dependabot-wish.yml: -------------------------------------------------------------------------------- 1 | 2 | - package-ecosystem: "gomod" 3 | directory: "/examples" 4 | schedule: 5 | interval: "weekly" 6 | day: "monday" 7 | time: "05:00" 8 | timezone: "America/New_York" 9 | labels: 10 | - "dependencies" 11 | commit-message: 12 | prefix: "chore" 13 | include: "scope" 14 | -------------------------------------------------------------------------------- /dependabot/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | updates: 4 | - package-ecosystem: "gomod" 5 | directory: "/" 6 | schedule: 7 | interval: "weekly" 8 | day: "monday" 9 | time: "05:00" 10 | timezone: "America/New_York" 11 | labels: 12 | - "dependencies" 13 | commit-message: 14 | prefix: "chore" 15 | include: "scope" 16 | 17 | - package-ecosystem: "github-actions" 18 | directory: "/" 19 | schedule: 20 | interval: "weekly" 21 | day: "monday" 22 | time: "05:00" 23 | timezone: "America/New_York" 24 | labels: 25 | - "dependencies" 26 | commit-message: 27 | prefix: "chore" 28 | include: "scope" 29 | 30 | - package-ecosystem: "docker" 31 | directory: "/" 32 | schedule: 33 | interval: "weekly" 34 | day: "monday" 35 | time: "05:00" 36 | timezone: "America/New_York" 37 | labels: 38 | - "dependencies" 39 | commit-message: 40 | prefix: "chore" 41 | include: "scope" 42 | -------------------------------------------------------------------------------- /dependabot/download-current.sh: -------------------------------------------------------------------------------- 1 | # NOTE(@andreynering): This is just a script to download dependabot.yml from 2 | # many of our repos. I used it to compare the contents to see which of them 3 | # were different from the base template. 4 | 5 | REPOS=$(gh repo list charmbracelet --visibility public --no-archived --limit 1000 --json "name,defaultBranchRef" -t '{{range .}}{{printf "%s %s\n" .name .defaultBranchRef.name}}{{end}}') 6 | REPOS=$(echo "$REPOS" | awk '$0 != "x" && $0 != ".github" && $0 != "meta" && $0 != "homebrew-tap" && $0 != "scoop-bucket"' | sort) 7 | 8 | rm -rf dependabot/current 9 | mkdir -p dependabot/current 10 | 11 | while read -r repo branch; do 12 | echo "Downloading $repo | $branch" 13 | curl -s https://raw.githubusercontent.com/charmbracelet/${repo}/refs/heads/${branch}/.github/dependabot.yml > dependabot/current/${repo}.yml 14 | done <<< "$REPOS" 15 | -------------------------------------------------------------------------------- /dependabot/run-workflow.sh: -------------------------------------------------------------------------------- 1 | # NOTE(@andreynering): This script runs the `dependabot-sync.yml` workflow for 2 | # all public repositories. 3 | 4 | REPOS=$(gh repo list charmbracelet --visibility public --no-archived --limit 1000 --json "name" -t '{{range .}}{{printf "%s\n" .name}}{{end}}') 5 | REPOS=$(echo "$REPOS" | awk '$0 != "x" && $0 != ".github" && $0 != "meta" && $0 != "homebrew-tap" && $0 != "scoop-bucket"' | sort) 6 | 7 | for repo in $REPOS; do 8 | echo "Dispatching dependabot-sync.yml for $repo" 9 | gh workflow run dependabot-sync.yml -f "repo_name=$repo" 10 | done 11 | -------------------------------------------------------------------------------- /dependabot/workflows/dependabot-sync.yml: -------------------------------------------------------------------------------- 1 | name: dependabot-sync 2 | on: 3 | schedule: 4 | - cron: "0 0 * * 0" # every Sunday at midnight 5 | workflow_dispatch: # allows manual triggering 6 | 7 | permissions: 8 | contents: write 9 | pull-requests: write 10 | 11 | jobs: 12 | dependabot-sync: 13 | uses: charmbracelet/meta/.github/workflows/dependabot-sync.yml@main 14 | with: 15 | repo_name: ${{ github.event.repository.name }} 16 | secrets: 17 | gh_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} 18 | -------------------------------------------------------------------------------- /footer.md: -------------------------------------------------------------------------------- 1 | --- 2 | 3 |
4 | Verifying the artifacts 5 | 6 | First, download the [`checksums.txt` file](https://github.com/charmbracelet/{{.ProjectName}}/releases/download/{{.Version}}/checksums.txt), for example, with `wget`: 7 | 8 | ```bash 9 | wget 'https://github.com/charmbracelet/{{.ProjectName}}/releases/download/{{.Tag}}/checksums.txt' 10 | ``` 11 | 12 | Then, verify it using [`cosign`](https://github.com/sigstore/cosign): 13 | 14 | ```bash 15 | cosign verify-blob \ 16 | --certificate-identity 'https://github.com/charmbracelet/meta/.github/workflows/goreleaser.yml@refs/heads/main' \ 17 | --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \ 18 | --cert 'https://github.com/charmbracelet/{{.ProjectName}}/releases/download/{{.Tag}}/checksums.txt.pem' \ 19 | --signature 'https://github.com/charmbracelet/{{.ProjectName}}/releases/download/{{.Tag}}/checksums.txt.sig' \ 20 | ./checksums.txt 21 | ``` 22 | 23 | If the output is `Verified OK`, you can safely use it to verify the checksums of other artifacts you downloaded from the release using `sha256sum`: 24 | 25 | ```bash 26 | sha256sum --ignore-missing -c checksums.txt 27 | ``` 28 | 29 | Done! You artifacts are now verified! 30 | 31 |
32 | 33 | The Charm logo 34 | 35 | Thoughts? Questions? We love hearing from you. Feel free to reach out on [Twitter](https://twitter.com/charmcli), [The Fediverse](https://mastodon.technology/@charm), or on [Discord](https://charm.sh/chat). 36 | -------------------------------------------------------------------------------- /footer_lib.md: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | The Charm logo 4 | 5 | Thoughts? Questions? We love hearing from you. Feel free to reach out on [Twitter](https://twitter.com/charmcli), [The Fediverse](https://mastodon.technology/@charm), or on [Discord](https://charm.sh/chat). 6 | -------------------------------------------------------------------------------- /golangci.yml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | run: 3 | tests: false 4 | linters: 5 | enable: 6 | - bodyclose 7 | - exhaustive 8 | - goconst 9 | - godot 10 | - gomoddirectives 11 | - goprintffuncname 12 | - gosec 13 | - misspell 14 | - nakedret 15 | - nestif 16 | - nilerr 17 | - noctx 18 | - nolintlint 19 | - prealloc 20 | - revive 21 | - rowserrcheck 22 | - sqlclosecheck 23 | - tparallel 24 | - unconvert 25 | - unparam 26 | - whitespace 27 | - wrapcheck 28 | exclusions: 29 | generated: lax 30 | presets: 31 | - common-false-positives 32 | issues: 33 | max-issues-per-linter: 0 34 | max-same-issues: 0 35 | formatters: 36 | enable: 37 | - gofumpt 38 | - goimports 39 | exclusions: 40 | generated: lax 41 | -------------------------------------------------------------------------------- /goreleaser-announce.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json 2 | 3 | version: 2 4 | announce: 5 | # will run only if release is a patch release 6 | skip: "{{ eq .Patch 0 }}" 7 | 8 | #twitter: 9 | # enabled: true 10 | # message_template: '{{ .ProjectName }} {{ .Version }} is out! Check it out: https://github.com/charmbracelet/{{ .ProjectName }}/releases/tag/{{ .Tag }}' 11 | 12 | mastodon: 13 | enabled: true 14 | message_template: "{{ .ProjectName }} {{ .Version }} is out! Check it out: https://github.com/charmbracelet/{{ .ProjectName }}/releases/tag/{{ .Tag }}" 15 | server: https://fosstodon.org 16 | 17 | discord: 18 | enabled: true 19 | message_template: "{{ .ProjectName }} {{ .Version }} is out! Check it out: https://github.com/charmbracelet/{{ .ProjectName }}/releases/tag/{{ .Tag }}" 20 | -------------------------------------------------------------------------------- /goreleaser-enterprise.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json 2 | 3 | version: 2 4 | variables: 5 | main: "" 6 | binary_name: "" 7 | description: "" 8 | ghcr_io_registry_owner: charmbracelet 9 | 10 | includes: 11 | - from_url: 12 | url: charmbracelet/meta/main/notarize.yaml 13 | 14 | before: 15 | hooks: 16 | - go mod tidy 17 | 18 | builds: 19 | - binary: "{{ with .Var.binary_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}" 20 | env: 21 | - CGO_ENABLED=0 22 | main: "{{ with .Var.main }}{{ . }}{{ else }}.{{ end }}" 23 | ldflags: -s -w -X main.Version=v{{ .Version }} -X main.CommitSHA={{ .Commit }} -X main.CommitDate={{ .CommitDate }} 24 | goos: 25 | - linux 26 | goarch: 27 | - amd64 28 | 29 | checksum: 30 | name_template: "checksums.txt" 31 | 32 | source: 33 | enabled: true 34 | 35 | sboms: 36 | - artifacts: archive 37 | - id: source 38 | artifacts: source 39 | 40 | snapshot: 41 | version_template: "{{ incpatch .Version }}-snapshot" 42 | 43 | nightly: 44 | version_template: "{{ incpatch .Version }}-devel" 45 | 46 | signs: 47 | - cmd: cosign 48 | certificate: "${artifact}.pem" 49 | args: 50 | - sign-blob 51 | - "--output-certificate=${certificate}" 52 | - "--output-signature=${signature}" 53 | - "${artifact}" 54 | - "--yes" 55 | artifacts: checksum 56 | output: true 57 | 58 | dockers: 59 | - image_templates: 60 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 61 | goarch: amd64 62 | build_flag_templates: 63 | - --platform=linux/amd64 64 | - --label=org.opencontainers.image.title={{ .ProjectName }} 65 | - --label=org.opencontainers.image.description={{ .Var.description }} 66 | - --label=org.opencontainers.image.source={{ .GitURL }} 67 | - --label=org.opencontainers.image.version=v{{ .Version }} 68 | - --label=org.opencontainers.image.created={{ .Date }} 69 | - --label=org.opencontainers.image.revision={{ .FullCommit }} 70 | - --label=org.opencontainers.image.licenses=MIT 71 | dockerfile: Dockerfile 72 | use: buildx 73 | 74 | docker_manifests: 75 | - name_template: "{{ if not .IsNightly }}ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:latest{{ end }}" 76 | image_templates: 77 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 78 | - name_template: "{{ if not .IsNightly }}ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Major }}.{{ .Minor }}{{ end }}" 79 | image_templates: 80 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 81 | - name_template: "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}" 82 | image_templates: 83 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 84 | - name_template: "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:{{ .Commit }}{{ if .IsNightly }}-devel{{ end }}" 85 | image_templates: 86 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 87 | - name_template: "{{ if .IsNightly }}ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:nightly{{ end }}" 88 | image_templates: 89 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 90 | 91 | docker_signs: 92 | - cmd: cosign 93 | artifacts: manifests 94 | output: true 95 | args: 96 | - "sign" 97 | - "${artifact}" 98 | - "--yes" 99 | 100 | git: 101 | tag_sort: semver 102 | 103 | release: 104 | prerelease: auto 105 | footer: 106 | from_url: 107 | url: https://raw.githubusercontent.com/charmbracelet/meta/main/footer.md 108 | -------------------------------------------------------------------------------- /goreleaser-full.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json 2 | 3 | version: 2 4 | variables: 5 | main: "" 6 | binary_name: "" 7 | description: "" 8 | maintainer: "" 9 | homepage: "https://charm.sh/" 10 | brew_commit_author_name: "" 11 | brew_commit_author_email: "" 12 | brew_owner: charmbracelet 13 | docker_io_registry_owner: charmcli 14 | ghcr_io_registry_owner: charmbracelet 15 | aur_project_name: "" 16 | scoop_name: "" 17 | 18 | includes: 19 | - from_url: 20 | url: charmbracelet/meta/main/notarize.yaml 21 | 22 | before: 23 | hooks: 24 | - go mod tidy 25 | - rm -rf completions 26 | - mkdir completions 27 | - rm -rf manpages 28 | - mkdir manpages 29 | - sh -c 'go run {{ with .Var.main }}{{ . }}{{ else }}.{{ end }} completion "bash" >./completions/{{ .ProjectName }}.bash' 30 | - sh -c 'go run {{ with .Var.main }}{{ . }}{{ else }}.{{ end }} completion "zsh" >./completions/{{ .ProjectName }}.zsh' 31 | - sh -c 'go run {{ with .Var.main }}{{ . }}{{ else }}.{{ end }} completion "fish" >./completions/{{ .ProjectName }}.fish' 32 | - sh -c 'go run {{ with .Var.main }}{{ . }}{{ else }}.{{ end }} man | gzip -c >./manpages/{{ .ProjectName }}.1.gz' 33 | 34 | gomod: 35 | proxy: true 36 | 37 | builds: 38 | - binary: "{{ with .Var.binary_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}" 39 | env: 40 | - CGO_ENABLED=0 41 | main: "{{ with .Var.main }}{{ . }}{{ else }}.{{ end }}" 42 | ldflags: -s -w -X main.Version=v{{ .Version }} -X main.CommitSHA={{ .Commit }} -X main.CommitDate={{ .CommitDate }} 43 | goos: 44 | - linux 45 | - darwin 46 | - windows 47 | - freebsd 48 | - openbsd 49 | - netbsd 50 | goarch: 51 | - amd64 52 | - arm64 53 | - "386" 54 | - arm 55 | goarm: 56 | - "6" 57 | - "7" 58 | ignore: 59 | - goos: windows 60 | goarch: arm64 61 | - goos: windows 62 | goarch: arm 63 | 64 | archives: 65 | - format_overrides: 66 | - goos: windows 67 | formats: zip 68 | name_template: >- 69 | {{ .ProjectName }}_ 70 | {{- .Version }}_ 71 | {{- title .Os }}_ 72 | {{- if eq .Arch "amd64" }}x86_64 73 | {{- else if eq .Arch "386" }}i386 74 | {{- else }}{{ .Arch }}{{ end }} 75 | {{- with .Arm}}v{{ . }}{{ end }} 76 | wrap_in_directory: true 77 | files: 78 | - README* 79 | - LICENSE* 80 | - manpages/* 81 | - completions/* 82 | 83 | nfpms: 84 | - vendor: charmbracelet 85 | homepage: "{{ .Var.homepage }}" 86 | maintainer: "{{ .Var.maintainer }}" 87 | description: "{{ .Var.description }}" 88 | file_name_template: >- 89 | {{- trimsuffix .ConventionalFileName .ConventionalExtension -}} 90 | {{- if and (eq .Arm "6") (eq .ConventionalExtension ".deb") }}6{{ end -}} 91 | {{- .ConventionalExtension -}} 92 | license: MIT 93 | formats: 94 | - apk 95 | - deb 96 | - rpm 97 | contents: 98 | - src: ./completions/{{ .ProjectName }}.bash 99 | dst: /etc/bash_completion.d/{{ .ProjectName }} 100 | - src: ./completions/{{ .ProjectName }}.fish 101 | dst: /usr/share/fish/vendor_completions.d/{{ .ProjectName }}.fish 102 | - src: ./completions/{{ .ProjectName }}.zsh 103 | dst: /usr/share/zsh/site-functions/_{{ .ProjectName }} 104 | - src: ./manpages/{{ .ProjectName }}.1.gz 105 | dst: /usr/share/man/man1/{{ .ProjectName }}.1.gz 106 | rpm: 107 | signature: 108 | key_file: '{{ if ne (index .Env "GPG_KEY_PATH") "" }}{{ .Env.GPG_KEY_PATH }}{{ else }}{{ end }}' 109 | deb: 110 | signature: 111 | key_file: '{{ if ne (index .Env "GPG_KEY_PATH") "" }}{{ .Env.GPG_KEY_PATH }}{{ else }}{{ end }}' 112 | 113 | furies: 114 | - account: "{{ with .Env.FURY_TOKEN }}charmcli{{ else }}{{ end }}" 115 | secret_name: FURY_TOKEN 116 | 117 | brews: 118 | - repository: 119 | owner: "{{ .Var.brew_owner }}" 120 | name: homebrew-tap 121 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 122 | commit_author: 123 | name: "{{ .Var.brew_commit_author_name }}" 124 | email: "{{ .Var.brew_commit_author_email }}" 125 | homepage: "{{ .Var.homepage }}" 126 | description: "{{ .Var.description }}" 127 | goarm: 7 128 | install: |- 129 | bin.install "{{ with .Var.binary_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}" 130 | bash_completion.install "completions/{{ .ProjectName }}.bash" => "{{ .ProjectName }}" 131 | zsh_completion.install "completions/{{ .ProjectName }}.zsh" => "_{{ .ProjectName }}" 132 | fish_completion.install "completions/{{ .ProjectName }}.fish" 133 | man1.install "manpages/{{ .ProjectName }}.1.gz" 134 | 135 | scoops: 136 | - repository: 137 | owner: "{{ .Var.brew_owner }}" 138 | name: scoop-bucket 139 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 140 | commit_author: 141 | name: "{{ .Var.brew_commit_author_name }}" 142 | email: "{{ .Var.brew_commit_author_email }}" 143 | name: "{{ with .Var.scoop_name }}{{ . }}{{ end }}" 144 | homepage: "{{ .Var.homepage }}" 145 | description: "{{ .Var.description }}" 146 | license: MIT 147 | 148 | aurs: 149 | - maintainers: ["{{ .Var.maintainer }}"] 150 | description: "{{ .Var.description }}" 151 | name: "{{ with .Var.aur_project_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}-bin" 152 | homepage: "{{ .Var.homepage }}" 153 | license: MIT 154 | private_key: "{{ .Env.AUR_KEY }}" 155 | git_url: "ssh://aur@aur.archlinux.org/{{ with .Var.aur_project_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}-bin.git" 156 | package: |- 157 | cd "${srcdir}/{{ .ProjectName }}_${pkgver}_Linux_${CARCH}" 158 | # bin 159 | install -Dm755 "./{{ .ProjectName }}" "${pkgdir}/usr/bin/{{ .ProjectName }}" 160 | # license 161 | mkdir -p "${pkgdir}/usr/share/licenses/{{ .ProjectName }}/" 162 | install -Dm644 ./LICENSE* "${pkgdir}/usr/share/licenses/{{ .ProjectName }}/" 163 | # completions 164 | mkdir -p "${pkgdir}/usr/share/bash-completion/completions/" 165 | mkdir -p "${pkgdir}/usr/share/zsh/site-functions/" 166 | mkdir -p "${pkgdir}/usr/share/fish/vendor_completions.d/" 167 | install -Dm644 "./completions/{{ .ProjectName }}.bash" "${pkgdir}/usr/share/bash-completion/completions/{{ .ProjectName }}" 168 | install -Dm644 "./completions/{{ .ProjectName }}.zsh" "${pkgdir}/usr/share/zsh/site-functions/_{{ .ProjectName }}" 169 | install -Dm644 "./completions/{{ .ProjectName }}.fish" "${pkgdir}/usr/share/fish/vendor_completions.d/{{ .ProjectName }}.fish" 170 | # man pages 171 | install -Dm644 "./manpages/{{ .ProjectName }}.1.gz" "${pkgdir}/usr/share/man/man1/{{ .ProjectName }}.1.gz" 172 | # readme 173 | mkdir -pv "${pkgdir}/usr/share/doc/{{ .ProjectName }}/" 174 | install -Dm644 README* "${pkgdir}/usr/share/doc/{{ .ProjectName }}/" 175 | 176 | nix: 177 | - repository: 178 | owner: "{{ .Var.brew_owner }}" 179 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 180 | name: nur 181 | homepage: "{{ .Var.homepage }}" 182 | description: "{{ .Var.description }}" 183 | license: mit 184 | extra_install: |- 185 | installManPage ./manpages/{{.ProjectName}}.1.gz 186 | installShellCompletion ./completions/* 187 | 188 | winget: 189 | - publisher: charmbracelet 190 | license: MIT 191 | copyright: Charmbracelet, Inc 192 | homepage: "{{ .Var.homepage }}" 193 | short_description: "{{ .Var.description }}" 194 | repository: 195 | owner: "{{ .Var.brew_owner }}" 196 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 197 | name: winget-pkgs 198 | branch: "{{.ProjectName}}-{{.Version}}" 199 | pull_request: 200 | enabled: true 201 | draft: false 202 | check_boxes: true 203 | base: 204 | owner: microsoft 205 | name: winget-pkgs 206 | branch: master 207 | 208 | checksum: 209 | name_template: "checksums.txt" 210 | 211 | source: 212 | enabled: true 213 | 214 | sboms: 215 | - artifacts: archive 216 | - id: source 217 | artifacts: source 218 | 219 | snapshot: 220 | version_template: "{{ incpatch .Version }}-snapshot" 221 | 222 | nightly: 223 | version_template: "{{ incpatch .Version }}-devel" 224 | 225 | changelog: 226 | sort: asc 227 | use: github 228 | filters: 229 | exclude: 230 | - "^test:" 231 | - "^chore" 232 | - "merge conflict" 233 | - Merge pull request 234 | - Merge remote-tracking branch 235 | - Merge branch 236 | - go mod tidy 237 | groups: 238 | - title: Dependency updates 239 | regexp: "^.*\\(deps\\)*:+.*$" 240 | order: 300 241 | - title: "New Features" 242 | regexp: "^.*feat[(\\w)]*:+.*$" 243 | order: 100 244 | - title: "Bug fixes" 245 | regexp: "^.*fix[(\\w)]*:+.*$" 246 | order: 200 247 | - title: "Documentation updates" 248 | regexp: "^.*docs[(\\w)]*:+.*$" 249 | order: 400 250 | - title: Other work 251 | order: 9999 252 | 253 | signs: 254 | - cmd: cosign 255 | certificate: "${artifact}.pem" 256 | args: 257 | - sign-blob 258 | - "--output-certificate=${certificate}" 259 | - "--output-signature=${signature}" 260 | - "${artifact}" 261 | - "--yes" 262 | artifacts: checksum 263 | output: true 264 | 265 | dockers: 266 | - image_templates: 267 | - "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64{{ end }}" 268 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 269 | goarch: amd64 270 | build_flag_templates: 271 | - --platform=linux/amd64 272 | - --label=org.opencontainers.image.title={{ .ProjectName }} 273 | - --label=org.opencontainers.image.description={{ .Var.description }} 274 | - --label=org.opencontainers.image.source={{ .GitURL }} 275 | - --label=org.opencontainers.image.version=v{{ .Version }} 276 | - --label=org.opencontainers.image.created={{ .Date }} 277 | - --label=org.opencontainers.image.revision={{ .FullCommit }} 278 | - --label=org.opencontainers.image.licenses=MIT 279 | dockerfile: Dockerfile 280 | use: buildx 281 | - image_templates: 282 | - "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64{{ end }}" 283 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 284 | goarch: arm64 285 | build_flag_templates: 286 | - --platform=linux/arm64 287 | - --label=org.opencontainers.image.title={{ .ProjectName }} 288 | - --label=org.opencontainers.image.description={{ .Var.description }} 289 | - --label=org.opencontainers.image.source={{ .GitURL }} 290 | - --label=org.opencontainers.image.version=v{{ .Version }} 291 | - --label=org.opencontainers.image.created={{ .Date }} 292 | - --label=org.opencontainers.image.revision={{ .FullCommit }} 293 | - --label=org.opencontainers.image.licenses=MIT 294 | dockerfile: Dockerfile 295 | use: buildx 296 | - image_templates: 297 | - "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7{{ end }}" 298 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 299 | goarch: arm 300 | goarm: "7" 301 | build_flag_templates: 302 | - --platform=linux/arm/v7 303 | - --label=org.opencontainers.image.title={{ .ProjectName }} 304 | - --label=org.opencontainers.image.description={{ .Var.description }} 305 | - --label=org.opencontainers.image.source={{ .GitURL }} 306 | - --label=org.opencontainers.image.version=v{{ .Version }} 307 | - --label=org.opencontainers.image.created={{ .Date }} 308 | - --label=org.opencontainers.image.revision={{ .FullCommit }} 309 | - --label=org.opencontainers.image.licenses=MIT 310 | dockerfile: Dockerfile 311 | use: buildx 312 | 313 | docker_manifests: 314 | - name_template: "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:latest{{ end }}" 315 | image_templates: 316 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 317 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 318 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 319 | - name_template: "{{ if not .IsNightly }}ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:latest{{ end }}" 320 | image_templates: 321 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 322 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 323 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 324 | - name_template: "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Major }}.{{ .Minor }}{{ end }}" 325 | image_templates: 326 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 327 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 328 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 329 | - name_template: "{{ if not .IsNightly }}ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Major }}.{{ .Minor }}{{ end }}" 330 | image_templates: 331 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 332 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 333 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 334 | - name_template: "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}{{ end }}" 335 | image_templates: 336 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 337 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 338 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 339 | - name_template: "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}" 340 | image_templates: 341 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 342 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 343 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 344 | 345 | docker_signs: 346 | - cmd: cosign 347 | artifacts: manifests 348 | output: true 349 | args: 350 | - "sign" 351 | - "${artifact}" 352 | - "--yes" 353 | 354 | git: 355 | tag_sort: semver 356 | 357 | release: 358 | prerelease: auto 359 | footer: 360 | from_url: 361 | url: https://raw.githubusercontent.com/charmbracelet/meta/main/footer.md 362 | -------------------------------------------------------------------------------- /goreleaser-glow.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json 2 | 3 | version: 2 4 | variables: 5 | description: "" 6 | maintainer: "" 7 | homepage: "https://charm.sh/" 8 | brew_commit_author_name: "" 9 | brew_commit_author_email: "" 10 | brew_owner: charmbracelet 11 | docker_io_registry_owner: charmcli 12 | ghcr_io_registry_owner: charmbracelet 13 | aur_project_name: "" 14 | 15 | includes: 16 | - from_url: 17 | url: charmbracelet/meta/main/notarize.yaml 18 | 19 | before: 20 | hooks: 21 | - go mod tidy 22 | - rm -rf completions 23 | - mkdir completions 24 | - rm -rf manpages 25 | - mkdir manpages 26 | - sh -c 'go run . completion bash >./completions/glow.bash' 27 | - sh -c 'go run . completion zsh >./completions/glow.zsh' 28 | - sh -c 'go run . completion fish >./completions/glow.fish' 29 | - sh -c 'go run . man | gzip -c >./manpages/glow.1.gz' 30 | 31 | gomod: 32 | proxy: true 33 | 34 | builds: 35 | - binary: "glow" 36 | env: 37 | - CGO_ENABLED=0 38 | ldflags: -s -w -X main.Version={{ .Version }} -X main.CommitSHA={{ .Commit }} -X main.CommitDate={{ .CommitDate }} 39 | goos: 40 | - linux 41 | - darwin 42 | - windows 43 | - freebsd 44 | - openbsd 45 | - netbsd 46 | goarch: 47 | - amd64 48 | - arm64 49 | - "386" 50 | - arm 51 | goarm: 52 | - "7" 53 | ignore: 54 | - goos: windows 55 | goarch: arm64 56 | - goos: windows 57 | goarm: "7" 58 | 59 | archives: 60 | - format_overrides: 61 | - goos: windows 62 | formats: zip 63 | name_template: >- 64 | {{ .ProjectName }}_ 65 | {{- .Version }}_ 66 | {{- title .Os }}_ 67 | {{- if eq .Arch "amd64" }}x86_64 68 | {{- else if eq .Arch "386" }}i386 69 | {{- else }}{{ .Arch }}{{ end }} 70 | wrap_in_directory: true 71 | files: 72 | - README* 73 | - LICENSE* 74 | - manpages/* 75 | - completions/* 76 | 77 | nfpms: 78 | - vendor: charmbracelet 79 | homepage: "{{ .Var.homepage }}" 80 | maintainer: "{{ .Var.maintainer }}" 81 | description: "{{ .Var.description }}" 82 | file_name_template: "{{ .ConventionalFileName }}" 83 | license: MIT 84 | formats: 85 | - apk 86 | - deb 87 | - rpm 88 | contents: 89 | - src: ./completions/{{ .ProjectName }}.bash 90 | dst: /etc/bash_completion.d/{{ .ProjectName }} 91 | - src: ./completions/{{ .ProjectName }}.fish 92 | dst: /usr/share/fish/vendor_completions.d/{{ .ProjectName }}.fish 93 | - src: ./completions/{{ .ProjectName }}.zsh 94 | dst: /usr/share/zsh/site-functions/_{{ .ProjectName }} 95 | - src: ./manpages/{{ .ProjectName }}.1.gz 96 | dst: /usr/share/man/man1/{{ .ProjectName }}.1.gz 97 | rpm: 98 | signature: 99 | key_file: '{{ if ne (index .Env "GPG_KEY_PATH") "" }}{{ .Env.GPG_KEY_PATH }}{{ else }}{{ end }}' 100 | deb: 101 | signature: 102 | key_file: '{{ if ne (index .Env "GPG_KEY_PATH") "" }}{{ .Env.GPG_KEY_PATH }}{{ else }}{{ end }}' 103 | 104 | furies: 105 | - account: "{{ with .Env.FURY_TOKEN }}charmcli{{ else }}{{ end }}" 106 | secret_name: FURY_TOKEN 107 | 108 | brews: 109 | - repository: 110 | owner: "{{ .Var.brew_owner }}" 111 | name: homebrew-tap 112 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 113 | commit_author: 114 | name: "{{ .Var.brew_commit_author_name }}" 115 | email: "{{ .Var.brew_commit_author_email }}" 116 | homepage: "{{ .Var.homepage }}" 117 | description: "{{ .Var.description }}" 118 | install: |- 119 | bin.install "glow" 120 | bash_completion.install "completions/{{ .ProjectName }}.bash" => "{{ .ProjectName }}" 121 | zsh_completion.install "completions/{{ .ProjectName }}.zsh" => "_{{ .ProjectName }}" 122 | fish_completion.install "completions/{{ .ProjectName }}.fish" 123 | man1.install "manpages/{{ .ProjectName }}.1.gz" 124 | 125 | scoops: 126 | - repository: 127 | owner: "{{ .Var.brew_owner }}" 128 | name: scoop-bucket 129 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 130 | commit_author: 131 | name: "{{ .Var.brew_commit_author_name }}" 132 | email: "{{ .Var.brew_commit_author_email }}" 133 | homepage: "{{ .Var.homepage }}" 134 | description: "{{ .Var.description }}" 135 | license: MIT 136 | 137 | aurs: 138 | - maintainers: ["{{ .Var.maintainer }}"] 139 | description: "{{ .Var.description }}" 140 | name: "{{ with .Var.aur_project_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}-bin" 141 | homepage: "{{ .Var.homepage }}" 142 | license: MIT 143 | private_key: "{{ .Env.AUR_KEY }}" 144 | git_url: "ssh://aur@aur.archlinux.org/{{ with .Var.aur_project_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}-bin.git" 145 | package: |- 146 | cd "${srcdir}/{{ .ProjectName }}_${pkgver}_Linux_${CARCH}" 147 | # bin 148 | install -Dm755 "./{{ .ProjectName }}" "${pkgdir}/usr/bin/{{ .ProjectName }}" 149 | # license 150 | mkdir -p "${pkgdir}/usr/share/licenses/{{ .ProjectName }}/" 151 | install -Dm644 ./LICENSE* "${pkgdir}/usr/share/licenses/{{ .ProjectName }}/" 152 | # completions 153 | mkdir -p "${pkgdir}/usr/share/bash-completion/completions/" 154 | mkdir -p "${pkgdir}/usr/share/zsh/site-functions/" 155 | mkdir -p "${pkgdir}/usr/share/fish/vendor_completions.d/" 156 | install -Dm644 "./completions/{{ .ProjectName }}.bash" "${pkgdir}/usr/share/bash-completion/completions/{{ .ProjectName }}" 157 | install -Dm644 "./completions/{{ .ProjectName }}.zsh" "${pkgdir}/usr/share/zsh/site-functions/_{{ .ProjectName }}" 158 | install -Dm644 "./completions/{{ .ProjectName }}.fish" "${pkgdir}/usr/share/fish/vendor_completions.d/{{ .ProjectName }}.fish" 159 | # man pages 160 | install -Dm644 "./manpages/{{ .ProjectName }}.1.gz" "${pkgdir}/usr/share/man/man1/{{ .ProjectName }}.1.gz" 161 | # readme 162 | mkdir -pv "${pkgdir}/usr/share/doc/{{ .ProjectName }}/" 163 | install -Dm644 README* "${pkgdir}/usr/share/doc/{{ .ProjectName }}/" 164 | 165 | nix: 166 | - repository: 167 | owner: "{{ .Var.brew_owner }}" 168 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 169 | name: nur 170 | homepage: "{{ .Var.homepage }}" 171 | description: "{{ .Var.description }}" 172 | license: mit 173 | extra_install: |- 174 | installManPage ./manpages/{{.ProjectName}}.1.gz 175 | installShellCompletion ./completions/* 176 | 177 | winget: 178 | - publisher: charmbracelet 179 | license: MIT 180 | copyright: Charmbracelet, Inc 181 | homepage: "{{ .Var.homepage }}" 182 | short_description: "{{ .Var.description }}" 183 | repository: 184 | owner: "{{ .Var.brew_owner }}" 185 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 186 | name: winget-pkgs 187 | branch: "{{.ProjectName}}-{{.Version}}" 188 | pull_request: 189 | enabled: true 190 | draft: false 191 | check_boxes: true 192 | base: 193 | owner: microsoft 194 | name: winget-pkgs 195 | branch: master 196 | checksum: 197 | name_template: "checksums.txt" 198 | 199 | source: 200 | enabled: true 201 | 202 | sboms: 203 | - artifacts: archive 204 | - id: source 205 | artifacts: source 206 | 207 | snapshot: 208 | version_template: "{{ incpatch .Version }}-snapshot" 209 | 210 | nightly: 211 | version_template: "{{ incpatch .Version }}-devel" 212 | 213 | changelog: 214 | sort: asc 215 | use: github 216 | filters: 217 | exclude: 218 | - "^docs:" 219 | - "^test:" 220 | groups: 221 | - title: "New Features" 222 | regexp: "^.*feat[(\\w)]*:+.*$" 223 | order: 0 224 | - title: "Bug fixes" 225 | regexp: "^.*fix[(\\w)]*:+.*$" 226 | order: 10 227 | - title: Others 228 | order: 999 229 | 230 | signs: 231 | - cmd: cosign 232 | certificate: "${artifact}.pem" 233 | args: 234 | - sign-blob 235 | - "--output-certificate=${certificate}" 236 | - "--output-signature=${signature}" 237 | - "${artifact}" 238 | - "--yes" 239 | artifacts: checksum 240 | output: true 241 | 242 | dockers: 243 | - image_templates: 244 | - "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64{{ end }}" 245 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 246 | goarch: amd64 247 | build_flag_templates: 248 | - --platform=linux/amd64 249 | - --label=org.opencontainers.image.title={{ .ProjectName }} 250 | - --label=org.opencontainers.image.description={{ .Var.description }} 251 | - --label=org.opencontainers.image.source={{ .GitURL }} 252 | - --label=org.opencontainers.image.version=v{{ .Version }} 253 | - --label=org.opencontainers.image.created={{ .Date }} 254 | - --label=org.opencontainers.image.revision={{ .FullCommit }} 255 | - --label=org.opencontainers.image.licenses=MIT 256 | dockerfile: Dockerfile 257 | use: buildx 258 | - image_templates: 259 | - "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64{{ end }}" 260 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 261 | goarch: arm64 262 | build_flag_templates: 263 | - --platform=linux/arm64 264 | - --label=org.opencontainers.image.title={{ .ProjectName }} 265 | - --label=org.opencontainers.image.description={{ .Var.description }} 266 | - --label=org.opencontainers.image.source={{ .GitURL }} 267 | - --label=org.opencontainers.image.version=v{{ .Version }} 268 | - --label=org.opencontainers.image.created={{ .Date }} 269 | - --label=org.opencontainers.image.revision={{ .FullCommit }} 270 | - --label=org.opencontainers.image.licenses=MIT 271 | dockerfile: Dockerfile 272 | use: buildx 273 | - image_templates: 274 | - "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7{{ end }}" 275 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 276 | goarch: arm 277 | goarm: "7" 278 | build_flag_templates: 279 | - --platform=linux/arm/v7 280 | - --label=org.opencontainers.image.title={{ .ProjectName }} 281 | - --label=org.opencontainers.image.description={{ .Var.description }} 282 | - --label=org.opencontainers.image.source={{ .GitURL }} 283 | - --label=org.opencontainers.image.version=v{{ .Version }} 284 | - --label=org.opencontainers.image.created={{ .Date }} 285 | - --label=org.opencontainers.image.revision={{ .FullCommit }} 286 | - --label=org.opencontainers.image.licenses=MIT 287 | dockerfile: Dockerfile 288 | use: buildx 289 | 290 | docker_manifests: 291 | - name_template: "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:latest{{ end }}" 292 | image_templates: 293 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 294 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 295 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 296 | - name_template: "{{ if not .IsNightly }}ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:latest{{ end }}" 297 | image_templates: 298 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 299 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 300 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 301 | - name_template: "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Major }}.{{ .Minor }}{{ end }}" 302 | image_templates: 303 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 304 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 305 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 306 | - name_template: "{{ if not .IsNightly }}ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Major }}.{{ .Minor }}{{ end }}" 307 | image_templates: 308 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 309 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 310 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 311 | - name_template: "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}{{ end }}" 312 | image_templates: 313 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 314 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 315 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 316 | - name_template: "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}" 317 | image_templates: 318 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 319 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 320 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 321 | 322 | docker_signs: 323 | - cmd: cosign 324 | artifacts: manifests 325 | output: true 326 | args: 327 | - "sign" 328 | - "${artifact}" 329 | - "--yes" 330 | 331 | git: 332 | tag_sort: semver 333 | 334 | release: 335 | prerelease: auto 336 | footer: 337 | from_url: 338 | url: https://raw.githubusercontent.com/charmbracelet/meta/main/footer.md 339 | 340 | snapcrafts: 341 | - publish: true 342 | summary: "{{ .Var.description }}" 343 | description: | 344 | Glow is a terminal based markdown reader designed from the ground up to bring out the beauty—and power—of the CLI. 345 | Use it to discover markdown files, read documentation directly on the command line and stash markdown files to your own private collection so you can read them anywhere. Glow will find local markdown files in subdirectories or a local Git repository. 346 | By the way, all data stashed is encrypted end-to-end: only you can decrypt it. More on that below. 347 | grade: stable # TODO: '{{ if or .IsNightly .IsSnapshot }}devel{{ else }}stable{{ end }}' 348 | confinement: strict 349 | license: MIT 350 | base: core20 351 | 352 | apps: 353 | glow: 354 | command: glow 355 | plugs: ["home", "network", "removable-media"] 356 | -------------------------------------------------------------------------------- /goreleaser-lib.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json 2 | 3 | version: 2 4 | before: 5 | hooks: ["go mod tidy"] 6 | builds: [skip: true] 7 | changelog: 8 | sort: asc 9 | use: github 10 | filters: 11 | exclude: 12 | - "^test:" 13 | - "^chore" 14 | - "merge conflict" 15 | - Merge pull request 16 | - Merge remote-tracking branch 17 | - Merge branch 18 | - go mod tidy 19 | groups: 20 | - title: Dependency updates 21 | regexp: "^.*\\(deps\\)*:+.*$" 22 | order: 300 23 | - title: "New Features" 24 | regexp: "^.*feat[(\\w)]*:+.*$" 25 | order: 100 26 | - title: "Bug fixes" 27 | regexp: "^.*fix[(\\w)]*:+.*$" 28 | order: 200 29 | - title: "Documentation updates" 30 | regexp: "^.*docs[(\\w)]*:+.*$" 31 | order: 400 32 | - title: Other work 33 | order: 9999 34 | 35 | git: 36 | tag_sort: semver 37 | 38 | release: 39 | prerelease: auto 40 | footer: 41 | from_url: 42 | url: https://raw.githubusercontent.com/charmbracelet/meta/main/footer_lib.md 43 | -------------------------------------------------------------------------------- /goreleaser-mods.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json 2 | 3 | version: 2 4 | variables: 5 | main: "" 6 | aur_project_name: "" 7 | 8 | homepage: "https://charm.sh/" 9 | brew_owner: charmbracelet 10 | description: "AI on the command line" 11 | github_url: "https://github.com/charmbracelet/mods" 12 | maintainer: "Carlos Becker " 13 | brew_commit_author_name: "Carlos Becker" 14 | brew_commit_author_email: "carlos@charm.sh" 15 | 16 | includes: 17 | - from_url: 18 | url: charmbracelet/meta/main/notarize.yaml 19 | 20 | before: 21 | hooks: 22 | - go mod tidy 23 | - rm -rf completions 24 | - mkdir completions 25 | - rm -rf manpages 26 | - mkdir manpages 27 | - sh -c 'go run . completion "bash" >./completions/{{ .ProjectName }}.bash' 28 | - sh -c 'go run . completion "zsh" >./completions/{{ .ProjectName }}.zsh' 29 | - sh -c 'go run . completion "fish" >./completions/{{ .ProjectName }}.fish' 30 | - sh -c 'go run . man | gzip -c >./manpages/{{ .ProjectName }}.1.gz' 31 | 32 | gomod: 33 | proxy: true 34 | 35 | builds: 36 | - env: 37 | - CGO_ENABLED=0 38 | main: "{{ with .Var.main }}{{ . }}{{ else }}.{{ end }}" 39 | ldflags: -s -w -X main.Version=v{{ .Version }} -X main.CommitSHA={{ .Commit }} -X main.CommitDate={{ .CommitDate }} 40 | targets: 41 | # supported modernc.org/sqlite platforms: 42 | # https://pkg.go.dev/modernc.org/sqlite#hdr-Supported_platforms_and_architectures 43 | - darwin_amd64_v1 44 | - darwin_arm64 45 | - freebsd_amd64_v1 46 | - freebsd_arm64 47 | - linux_386 48 | - linux_amd64_v1 49 | - linux_arm_7 50 | - linux_arm64 51 | - windows_amd64_v1 52 | - windows_arm64 53 | 54 | archives: 55 | - format_overrides: 56 | - goos: windows 57 | formats: zip 58 | name_template: >- 59 | {{ .ProjectName }}_ 60 | {{- .Version }}_ 61 | {{- title .Os }}_ 62 | {{- if eq .Arch "amd64" }}x86_64 63 | {{- else if eq .Arch "386" }}i386 64 | {{- else }}{{ .Arch }}{{ end }} 65 | wrap_in_directory: true 66 | files: 67 | - README* 68 | - LICENSE* 69 | - manpages/* 70 | - completions/* 71 | 72 | nfpms: 73 | - vendor: charmbracelet 74 | homepage: "{{ .Var.homepage }}" 75 | maintainer: "{{ .Var.maintainer }}" 76 | file_name_template: "{{ .ConventionalFileName }}" 77 | license: MIT 78 | contents: 79 | - src: ./completions/{{ .ProjectName }}.bash 80 | dst: /etc/bash_completion.d/{{ .ProjectName }} 81 | - src: ./completions/{{ .ProjectName }}.fish 82 | dst: /usr/share/fish/vendor_completions.d/{{ .ProjectName }}.fish 83 | - src: ./completions/{{ .ProjectName }}.zsh 84 | dst: /usr/share/zsh/site-functions/_{{ .ProjectName }} 85 | - src: ./manpages/{{ .ProjectName }}.1.gz 86 | dst: /usr/share/man/man1/{{ .ProjectName }}.1.gz 87 | formats: 88 | - apk 89 | - deb 90 | - rpm 91 | rpm: 92 | signature: 93 | key_file: '{{ if ne (index .Env "GPG_KEY_PATH") "" }}{{ .Env.GPG_KEY_PATH }}{{ else }}{{ end }}' 94 | deb: 95 | signature: 96 | key_file: '{{ if ne (index .Env "GPG_KEY_PATH") "" }}{{ .Env.GPG_KEY_PATH }}{{ else }}{{ end }}' 97 | 98 | furies: 99 | - account: "{{ with .Env.FURY_TOKEN }}charmcli{{ else }}{{ end }}" 100 | secret_name: FURY_TOKEN 101 | 102 | brews: 103 | - repository: 104 | owner: "{{ .Var.brew_owner }}" 105 | name: homebrew-tap 106 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 107 | commit_author: 108 | name: "{{ .Var.brew_commit_author_name }}" 109 | email: "{{ .Var.brew_commit_author_email }}" 110 | homepage: "{{ .Var.homepage }}" 111 | description: "{{ .Var.description }}" 112 | extra_install: |- 113 | bash_completion.install "completions/{{ .ProjectName }}.bash" => "{{ .ProjectName }}" 114 | zsh_completion.install "completions/{{ .ProjectName }}.zsh" => "_{{ .ProjectName }}" 115 | fish_completion.install "completions/{{ .ProjectName }}.fish" 116 | man1.install "manpages/{{ .ProjectName }}.1.gz" 117 | 118 | scoops: 119 | - repository: 120 | owner: "{{ .Var.brew_owner }}" 121 | name: scoop-bucket 122 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 123 | commit_author: 124 | name: "{{ .Var.brew_commit_author_name }}" 125 | email: "{{ .Var.brew_commit_author_email }}" 126 | homepage: "{{ .Var.homepage }}" 127 | description: "{{ .Var.description }}" 128 | license: MIT 129 | 130 | aurs: 131 | - maintainers: ["{{ .Var.maintainer }}"] 132 | description: "{{ .Var.description }}" 133 | name: "{{ with .Var.aur_project_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}-bin" 134 | homepage: "{{ .Var.homepage }}" 135 | license: MIT 136 | private_key: "{{ .Env.AUR_KEY }}" 137 | git_url: "ssh://aur@aur.archlinux.org/{{ with .Var.aur_project_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}-bin.git" 138 | package: |- 139 | cd "${srcdir}/{{ .ProjectName }}_${pkgver}_Linux_${CARCH}" 140 | # bin 141 | install -Dm755 "./{{ .ProjectName }}" "${pkgdir}/usr/bin/{{ .ProjectName }}" 142 | # license 143 | mkdir -p "${pkgdir}/usr/share/licenses/{{ .ProjectName }}/" 144 | install -Dm644 ./LICENSE* "${pkgdir}/usr/share/licenses/{{ .ProjectName }}/" 145 | # completions 146 | mkdir -p "${pkgdir}/usr/share/bash-completion/completions/" 147 | mkdir -p "${pkgdir}/usr/share/zsh/site-functions/" 148 | mkdir -p "${pkgdir}/usr/share/fish/vendor_completions.d/" 149 | install -Dm644 "./completions/{{ .ProjectName }}.bash" "${pkgdir}/usr/share/bash-completion/completions/{{ .ProjectName }}" 150 | install -Dm644 "./completions/{{ .ProjectName }}.zsh" "${pkgdir}/usr/share/zsh/site-functions/_{{ .ProjectName }}" 151 | install -Dm644 "./completions/{{ .ProjectName }}.fish" "${pkgdir}/usr/share/fish/vendor_completions.d/{{ .ProjectName }}.fish" 152 | # man pages 153 | install -Dm644 "./manpages/{{ .ProjectName }}.1.gz" "${pkgdir}/usr/share/man/man1/{{ .ProjectName }}.1.gz" 154 | # readme 155 | mkdir -pv "${pkgdir}/usr/share/doc/{{ .ProjectName }}/" 156 | install -Dm644 README* "${pkgdir}/usr/share/doc/{{ .ProjectName }}/" 157 | 158 | nix: 159 | - repository: 160 | owner: "{{ .Var.brew_owner }}" 161 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 162 | name: nur 163 | homepage: "{{ .Var.homepage }}" 164 | description: "{{ .Var.description }}" 165 | license: mit 166 | extra_install: |- 167 | installManPage ./manpages/{{.ProjectName}}.1.gz 168 | installShellCompletion ./completions/* 169 | 170 | winget: 171 | - publisher: charmbracelet 172 | license: MIT 173 | copyright: Charmbracelet, Inc 174 | homepage: "{{ .Var.homepage }}" 175 | short_description: "{{ .Var.description }}" 176 | repository: 177 | owner: "{{ .Var.brew_owner }}" 178 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 179 | name: winget-pkgs 180 | branch: "{{.ProjectName}}-{{.Version}}" 181 | pull_request: 182 | enabled: true 183 | draft: false 184 | check_boxes: true 185 | base: 186 | owner: microsoft 187 | name: winget-pkgs 188 | branch: master 189 | 190 | checksum: 191 | name_template: "checksums.txt" 192 | 193 | source: 194 | enabled: true 195 | 196 | sboms: 197 | - artifacts: archive 198 | - id: source 199 | artifacts: source 200 | 201 | snapshot: 202 | version_template: "{{ incpatch .Version }}-snapshot" 203 | 204 | nightly: 205 | version_template: "{{ incpatch .Version }}-devel" 206 | 207 | changelog: 208 | sort: asc 209 | use: github 210 | filters: 211 | exclude: 212 | - "^test:" 213 | - "^chore" 214 | - "merge conflict" 215 | - Merge pull request 216 | - Merge remote-tracking branch 217 | - Merge branch 218 | - go mod tidy 219 | groups: 220 | - title: Dependency updates 221 | regexp: "^.*\\(deps\\)*:+.*$" 222 | order: 300 223 | - title: "New Features" 224 | regexp: "^.*feat[(\\w)]*:+.*$" 225 | order: 100 226 | - title: "Bug fixes" 227 | regexp: "^.*fix[(\\w)]*:+.*$" 228 | order: 200 229 | - title: "Documentation updates" 230 | regexp: "^.*docs[(\\w)]*:+.*$" 231 | order: 400 232 | - title: Other work 233 | order: 9999 234 | 235 | signs: 236 | - cmd: cosign 237 | certificate: "${artifact}.pem" 238 | args: 239 | - sign-blob 240 | - "--output-certificate=${certificate}" 241 | - "--output-signature=${signature}" 242 | - "${artifact}" 243 | - "--yes" 244 | artifacts: checksum 245 | output: true 246 | 247 | git: 248 | tag_sort: semver 249 | 250 | release: 251 | prerelease: auto 252 | footer: 253 | from_url: 254 | url: https://raw.githubusercontent.com/charmbracelet/meta/main/footer.md 255 | -------------------------------------------------------------------------------- /goreleaser-semi.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json 2 | 3 | version: 2 4 | variables: 5 | main: "" 6 | binary_name: "" 7 | description: "" 8 | maintainer: "" 9 | homepage: "https://charm.sh/" 10 | brew_commit_author_name: "" 11 | brew_commit_author_email: "" 12 | brew_owner: charmbracelet 13 | docker_io_registry_owner: charmcli 14 | ghcr_io_registry_owner: charmbracelet 15 | aur_project_name: "" 16 | 17 | includes: 18 | - from_url: 19 | url: charmbracelet/meta/main/notarize.yaml 20 | 21 | before: 22 | hooks: 23 | - go mod tidy 24 | - rm -rf completions 25 | - mkdir completions 26 | - rm -rf manpages 27 | - mkdir manpages 28 | - sh -c 'go run {{ with .Var.main }}{{ . }}{{ else }}.{{ end }} completion "bash" >./completions/{{ .ProjectName }}.bash' 29 | - sh -c 'go run {{ with .Var.main }}{{ . }}{{ else }}.{{ end }} completion "zsh" >./completions/{{ .ProjectName }}.zsh' 30 | - sh -c 'go run {{ with .Var.main }}{{ . }}{{ else }}.{{ end }} completion "fish" >./completions/{{ .ProjectName }}.fish' 31 | - sh -c 'go run {{ with .Var.main }}{{ . }}{{ else }}.{{ end }} man | gzip -c >./manpages/{{ .ProjectName }}.1.gz' 32 | 33 | gomod: 34 | proxy: true 35 | 36 | builds: 37 | - binary: "{{ with .Var.binary_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}" 38 | env: 39 | - CGO_ENABLED=0 40 | main: "{{ with .Var.main }}{{ . }}{{ else }}.{{ end }}" 41 | ldflags: -s -w -X main.Version=v{{ .Version }} -X main.CommitSHA={{ .Commit }} -X main.CommitDate={{ .CommitDate }} 42 | goos: 43 | - linux 44 | - freebsd 45 | - darwin 46 | - windows 47 | goarch: 48 | - amd64 49 | - arm64 50 | - "386" 51 | - arm 52 | goarm: 53 | - "7" 54 | ignore: 55 | - goos: windows 56 | goarch: arm64 57 | - goos: windows 58 | goarm: "7" 59 | - goos: windows 60 | goarch: "386" 61 | - goos: freebsd 62 | goarch: arm64 63 | - goos: freebsd 64 | goarch: "386" 65 | - goos: freebsd 66 | goarm: "7" 67 | 68 | archives: 69 | - format_overrides: 70 | - goos: windows 71 | formats: zip 72 | name_template: >- 73 | {{ .ProjectName }}_ 74 | {{- .Version }}_ 75 | {{- title .Os }}_ 76 | {{- if eq .Arch "amd64" }}x86_64 77 | {{- else if eq .Arch "386" }}i386 78 | {{- else }}{{ .Arch }}{{ end }} 79 | wrap_in_directory: true 80 | files: 81 | - README* 82 | - LICENSE* 83 | - manpages/* 84 | - completions/* 85 | 86 | nfpms: 87 | - vendor: charmbracelet 88 | homepage: "{{ .Var.homepage }}" 89 | maintainer: "{{ .Var.maintainer }}" 90 | description: "{{ .Var.description }}" 91 | file_name_template: "{{ .ConventionalFileName }}" 92 | license: MIT 93 | formats: 94 | - apk 95 | - deb 96 | - rpm 97 | contents: 98 | - src: ./completions/{{ .ProjectName }}.bash 99 | dst: /etc/bash_completion.d/{{ .ProjectName }} 100 | - src: ./completions/{{ .ProjectName }}.fish 101 | dst: /usr/share/fish/vendor_completions.d/{{ .ProjectName }}.fish 102 | - src: ./completions/{{ .ProjectName }}.zsh 103 | dst: /usr/share/zsh/site-functions/_{{ .ProjectName }} 104 | - src: ./manpages/{{ .ProjectName }}.1.gz 105 | dst: /usr/share/man/man1/{{ .ProjectName }}.1.gz 106 | rpm: 107 | signature: 108 | key_file: '{{ if ne (index .Env "GPG_KEY_PATH") "" }}{{ .Env.GPG_KEY_PATH }}{{ else }}{{ end }}' 109 | deb: 110 | signature: 111 | key_file: '{{ if ne (index .Env "GPG_KEY_PATH") "" }}{{ .Env.GPG_KEY_PATH }}{{ else }}{{ end }}' 112 | 113 | furies: 114 | - account: "{{ with .Env.FURY_TOKEN }}charmcli{{ else }}{{ end }}" 115 | secret_name: FURY_TOKEN 116 | 117 | brews: 118 | - repository: 119 | owner: "{{ .Var.brew_owner }}" 120 | name: homebrew-tap 121 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 122 | commit_author: 123 | name: "{{ .Var.brew_commit_author_name }}" 124 | email: "{{ .Var.brew_commit_author_email }}" 125 | homepage: "{{ .Var.homepage }}" 126 | description: "{{ .Var.description }}" 127 | install: |- 128 | bin.install "{{ with .Var.binary_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}" 129 | bash_completion.install "completions/{{ .ProjectName }}.bash" => "{{ .ProjectName }}" 130 | zsh_completion.install "completions/{{ .ProjectName }}.zsh" => "_{{ .ProjectName }}" 131 | fish_completion.install "completions/{{ .ProjectName }}.fish" 132 | man1.install "manpages/{{ .ProjectName }}.1.gz" 133 | 134 | scoops: 135 | - repository: 136 | owner: "{{ .Var.brew_owner }}" 137 | name: scoop-bucket 138 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 139 | commit_author: 140 | name: "{{ .Var.brew_commit_author_name }}" 141 | email: "{{ .Var.brew_commit_author_email }}" 142 | homepage: "{{ .Var.homepage }}" 143 | description: "{{ .Var.description }}" 144 | license: MIT 145 | 146 | aurs: 147 | - maintainers: ["{{ .Var.maintainer }}"] 148 | description: "{{ .Var.description }}" 149 | name: "{{ with .Var.aur_project_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}-bin" 150 | homepage: "{{ .Var.homepage }}" 151 | license: MIT 152 | private_key: "{{ .Env.AUR_KEY }}" 153 | git_url: "ssh://aur@aur.archlinux.org/{{ with .Var.aur_project_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}-bin.git" 154 | package: |- 155 | cd "${srcdir}/{{ .ProjectName }}_${pkgver}_Linux_${CARCH}" 156 | # bin 157 | install -Dm755 "./{{ .ProjectName }}" "${pkgdir}/usr/bin/{{ .ProjectName }}" 158 | # license 159 | mkdir -p "${pkgdir}/usr/share/licenses/{{ .ProjectName }}/" 160 | install -Dm644 ./LICENSE* "${pkgdir}/usr/share/licenses/{{ .ProjectName }}/" 161 | # completions 162 | mkdir -p "${pkgdir}/usr/share/bash-completion/completions/" 163 | mkdir -p "${pkgdir}/usr/share/zsh/site-functions/" 164 | mkdir -p "${pkgdir}/usr/share/fish/vendor_completions.d/" 165 | install -Dm644 "./completions/{{ .ProjectName }}.bash" "${pkgdir}/usr/share/bash-completion/completions/{{ .ProjectName }}" 166 | install -Dm644 "./completions/{{ .ProjectName }}.zsh" "${pkgdir}/usr/share/zsh/site-functions/_{{ .ProjectName }}" 167 | install -Dm644 "./completions/{{ .ProjectName }}.fish" "${pkgdir}/usr/share/fish/vendor_completions.d/{{ .ProjectName }}.fish" 168 | # man pages 169 | install -Dm644 "./manpages/{{ .ProjectName }}.1.gz" "${pkgdir}/usr/share/man/man1/{{ .ProjectName }}.1.gz" 170 | # readme 171 | mkdir -pv "${pkgdir}/usr/share/doc/{{ .ProjectName }}/" 172 | install -Dm644 README* "${pkgdir}/usr/share/doc/{{ .ProjectName }}/" 173 | 174 | nix: 175 | - repository: 176 | owner: "{{ .Var.brew_owner }}" 177 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 178 | name: nur 179 | homepage: "{{ .Var.homepage }}" 180 | description: "{{ .Var.description }}" 181 | license: mit 182 | extra_install: |- 183 | installManPage ./manpages/{{.ProjectName}}.1.gz 184 | installShellCompletion ./completions/* 185 | 186 | winget: 187 | - publisher: charmbracelet 188 | license: MIT 189 | copyright: Charmbracelet, Inc 190 | homepage: "{{ .Var.homepage }}" 191 | short_description: "{{ .Var.description }}" 192 | repository: 193 | owner: "{{ .Var.brew_owner }}" 194 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 195 | name: winget-pkgs 196 | branch: "{{.ProjectName}}-{{.Version}}" 197 | pull_request: 198 | enabled: true 199 | draft: false 200 | check_boxes: true 201 | base: 202 | owner: microsoft 203 | name: winget-pkgs 204 | branch: master 205 | checksum: 206 | name_template: "checksums.txt" 207 | 208 | source: 209 | enabled: true 210 | 211 | sboms: 212 | - artifacts: archive 213 | - id: source 214 | artifacts: source 215 | 216 | snapshot: 217 | version_template: "{{ incpatch .Version }}-snapshot" 218 | 219 | nightly: 220 | version_template: "{{ incpatch .Version }}-devel" 221 | 222 | changelog: 223 | sort: asc 224 | use: github 225 | filters: 226 | exclude: 227 | - "^test:" 228 | - "^chore" 229 | - "merge conflict" 230 | - Merge pull request 231 | - Merge remote-tracking branch 232 | - Merge branch 233 | - go mod tidy 234 | groups: 235 | - title: Dependency updates 236 | regexp: "^.*\\(deps\\)*:+.*$" 237 | order: 300 238 | - title: "New Features" 239 | regexp: "^.*feat[(\\w)]*:+.*$" 240 | order: 100 241 | - title: "Bug fixes" 242 | regexp: "^.*fix[(\\w)]*:+.*$" 243 | order: 200 244 | - title: "Documentation updates" 245 | regexp: "^.*docs[(\\w)]*:+.*$" 246 | order: 400 247 | - title: Other work 248 | order: 9999 249 | 250 | signs: 251 | - cmd: cosign 252 | certificate: "${artifact}.pem" 253 | args: 254 | - sign-blob 255 | - "--output-certificate=${certificate}" 256 | - "--output-signature=${signature}" 257 | - "${artifact}" 258 | - "--yes" 259 | artifacts: checksum 260 | output: true 261 | 262 | dockers: 263 | - image_templates: 264 | - "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64{{ end }}" 265 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 266 | goarch: amd64 267 | build_flag_templates: 268 | - --platform=linux/amd64 269 | - --label=org.opencontainers.image.title={{ .ProjectName }} 270 | - --label=org.opencontainers.image.description={{ .Var.description }} 271 | - --label=org.opencontainers.image.source={{ .GitURL }} 272 | - --label=org.opencontainers.image.version=v{{ .Version }} 273 | - --label=org.opencontainers.image.created={{ .Date }} 274 | - --label=org.opencontainers.image.revision={{ .FullCommit }} 275 | - --label=org.opencontainers.image.licenses=MIT 276 | dockerfile: Dockerfile 277 | use: buildx 278 | - image_templates: 279 | - "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64{{ end }}" 280 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 281 | goarch: arm64 282 | build_flag_templates: 283 | - --platform=linux/arm64 284 | - --label=org.opencontainers.image.title={{ .ProjectName }} 285 | - --label=org.opencontainers.image.description={{ .Var.description }} 286 | - --label=org.opencontainers.image.source={{ .GitURL }} 287 | - --label=org.opencontainers.image.version=v{{ .Version }} 288 | - --label=org.opencontainers.image.created={{ .Date }} 289 | - --label=org.opencontainers.image.revision={{ .FullCommit }} 290 | - --label=org.opencontainers.image.licenses=MIT 291 | dockerfile: Dockerfile 292 | use: buildx 293 | - image_templates: 294 | - "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7{{ end }}" 295 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 296 | goarch: arm 297 | goarm: "7" 298 | build_flag_templates: 299 | - --platform=linux/arm/v7 300 | - --label=org.opencontainers.image.title={{ .ProjectName }} 301 | - --label=org.opencontainers.image.description={{ .Var.description }} 302 | - --label=org.opencontainers.image.source={{ .GitURL }} 303 | - --label=org.opencontainers.image.version=v{{ .Version }} 304 | - --label=org.opencontainers.image.created={{ .Date }} 305 | - --label=org.opencontainers.image.revision={{ .FullCommit }} 306 | - --label=org.opencontainers.image.licenses=MIT 307 | dockerfile: Dockerfile 308 | use: buildx 309 | 310 | docker_manifests: 311 | - name_template: "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:latest{{ end }}" 312 | image_templates: 313 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 314 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 315 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 316 | - name_template: "{{ if not .IsNightly }}ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:latest{{ end }}" 317 | image_templates: 318 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 319 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 320 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 321 | - name_template: "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Major }}.{{ .Minor }}{{ end }}" 322 | image_templates: 323 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 324 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 325 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 326 | - name_template: "{{ if not .IsNightly }}ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Major }}.{{ .Minor }}{{ end }}" 327 | image_templates: 328 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 329 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 330 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 331 | - name_template: "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}{{ end }}" 332 | image_templates: 333 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 334 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 335 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 336 | - name_template: "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}" 337 | image_templates: 338 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 339 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 340 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 341 | 342 | docker_signs: 343 | - cmd: cosign 344 | artifacts: manifests 345 | output: true 346 | args: 347 | - "sign" 348 | - "${artifact}" 349 | - "--yes" 350 | 351 | git: 352 | tag_sort: semver 353 | 354 | release: 355 | prerelease: auto 356 | footer: 357 | from_url: 358 | url: https://raw.githubusercontent.com/charmbracelet/meta/main/footer.md 359 | -------------------------------------------------------------------------------- /goreleaser-sequin.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json 2 | 3 | version: 2 4 | variables: 5 | main: "" 6 | aur_project_name: "" 7 | 8 | homepage: "https://charm.sh/" 9 | brew_owner: charmbracelet 10 | description: "Human-readable ANSI sequences." 11 | github_url: "https://github.com/charmbracelet/sequin" 12 | maintainer: "Carlos A Becker " 13 | brew_commit_author_name: "Carlos A Becker" 14 | brew_commit_author_email: "carlos@charm.sh" 15 | 16 | includes: 17 | - from_url: 18 | url: charmbracelet/meta/main/notarize.yaml 19 | 20 | before: 21 | hooks: 22 | - go mod tidy 23 | - rm -rf completions 24 | - mkdir completions 25 | - rm -rf manpages 26 | - mkdir manpages 27 | - sh -c 'go run . completion "bash" >./completions/{{ .ProjectName }}.bash' 28 | - sh -c 'go run . completion "zsh" >./completions/{{ .ProjectName }}.zsh' 29 | - sh -c 'go run . completion "fish" >./completions/{{ .ProjectName }}.fish' 30 | - sh -c 'go run . man | gzip -c >./manpages/{{ .ProjectName }}.1.gz' 31 | 32 | gomod: 33 | proxy: true 34 | 35 | builds: 36 | - env: 37 | - CGO_ENABLED=0 38 | main: "{{ with .Var.main }}{{ . }}{{ else }}.{{ end }}" 39 | ldflags: -s -w -X main.Version=v{{ .Version }} -X main.CommitSHA={{ .Commit }} -X main.CommitDate={{ .CommitDate }} 40 | goos: 41 | - linux 42 | - darwin 43 | - windows 44 | - freebsd 45 | - openbsd 46 | - netbsd 47 | goarch: 48 | - amd64 49 | - arm64 50 | - "386" 51 | - arm 52 | goarm: 53 | - "7" 54 | ignore: 55 | - goos: windows 56 | goarch: arm64 57 | - goos: windows 58 | goarm: "7" 59 | 60 | archives: 61 | - format_overrides: 62 | - goos: windows 63 | formats: zip 64 | name_template: >- 65 | {{ .ProjectName }}_ 66 | {{- .Version }}_ 67 | {{- title .Os }}_ 68 | {{- if eq .Arch "amd64" }}x86_64 69 | {{- else if eq .Arch "386" }}i386 70 | {{- else }}{{ .Arch }}{{ end }} 71 | wrap_in_directory: true 72 | files: 73 | - README* 74 | - LICENSE* 75 | - manpages/* 76 | - completions/* 77 | 78 | nfpms: 79 | - vendor: charmbracelet 80 | homepage: "{{ .Var.homepage }}" 81 | maintainer: "{{ .Var.maintainer }}" 82 | file_name_template: "{{ .ConventionalFileName }}" 83 | license: MIT 84 | contents: 85 | - src: ./completions/{{ .ProjectName }}.bash 86 | dst: /etc/bash_completion.d/{{ .ProjectName }} 87 | - src: ./completions/{{ .ProjectName }}.fish 88 | dst: /usr/share/fish/vendor_completions.d/{{ .ProjectName }}.fish 89 | - src: ./completions/{{ .ProjectName }}.zsh 90 | dst: /usr/share/zsh/site-functions/_{{ .ProjectName }} 91 | - src: ./manpages/{{ .ProjectName }}.1.gz 92 | dst: /usr/share/man/man1/{{ .ProjectName }}.1.gz 93 | formats: 94 | - apk 95 | - deb 96 | - rpm 97 | rpm: 98 | signature: 99 | key_file: '{{ if ne (index .Env "GPG_KEY_PATH") "" }}{{ .Env.GPG_KEY_PATH }}{{ else }}{{ end }}' 100 | deb: 101 | signature: 102 | key_file: '{{ if ne (index .Env "GPG_KEY_PATH") "" }}{{ .Env.GPG_KEY_PATH }}{{ else }}{{ end }}' 103 | 104 | furies: 105 | - account: "{{ with .Env.FURY_TOKEN }}charmcli{{ else }}{{ end }}" 106 | secret_name: FURY_TOKEN 107 | 108 | brews: 109 | - repository: 110 | owner: "{{ .Var.brew_owner }}" 111 | name: homebrew-tap 112 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 113 | commit_author: 114 | name: "{{ .Var.brew_commit_author_name }}" 115 | email: "{{ .Var.brew_commit_author_email }}" 116 | homepage: "{{ .Var.homepage }}" 117 | description: "{{ .Var.description }}" 118 | extra_install: |- 119 | bash_completion.install "completions/{{ .ProjectName }}.bash" => "{{ .ProjectName }}" 120 | zsh_completion.install "completions/{{ .ProjectName }}.zsh" => "_{{ .ProjectName }}" 121 | fish_completion.install "completions/{{ .ProjectName }}.fish" 122 | man1.install "manpages/{{ .ProjectName }}.1.gz" 123 | 124 | scoops: 125 | - repository: 126 | owner: "{{ .Var.brew_owner }}" 127 | name: scoop-bucket 128 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 129 | commit_author: 130 | name: "{{ .Var.brew_commit_author_name }}" 131 | email: "{{ .Var.brew_commit_author_email }}" 132 | homepage: "{{ .Var.homepage }}" 133 | description: "{{ .Var.description }}" 134 | license: MIT 135 | 136 | aurs: 137 | - maintainers: ["{{ .Var.maintainer }}"] 138 | description: "{{ .Var.description }}" 139 | name: "{{ with .Var.aur_project_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}-bin" 140 | homepage: "{{ .Var.homepage }}" 141 | license: MIT 142 | private_key: "{{ .Env.AUR_KEY }}" 143 | git_url: "ssh://aur@aur.archlinux.org/{{ with .Var.aur_project_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}-bin.git" 144 | package: |- 145 | cd "${srcdir}/{{ .ProjectName }}_${pkgver}_Linux_${CARCH}" 146 | # bin 147 | install -Dm755 "./{{ .ProjectName }}" "${pkgdir}/usr/bin/{{ .ProjectName }}" 148 | # license 149 | mkdir -p "${pkgdir}/usr/share/licenses/{{ .ProjectName }}/" 150 | install -Dm644 ./LICENSE* "${pkgdir}/usr/share/licenses/{{ .ProjectName }}/" 151 | # completions 152 | mkdir -p "${pkgdir}/usr/share/bash-completion/completions/" 153 | mkdir -p "${pkgdir}/usr/share/zsh/site-functions/" 154 | mkdir -p "${pkgdir}/usr/share/fish/vendor_completions.d/" 155 | install -Dm644 "./completions/{{ .ProjectName }}.bash" "${pkgdir}/usr/share/bash-completion/completions/{{ .ProjectName }}" 156 | install -Dm644 "./completions/{{ .ProjectName }}.zsh" "${pkgdir}/usr/share/zsh/site-functions/_{{ .ProjectName }}" 157 | install -Dm644 "./completions/{{ .ProjectName }}.fish" "${pkgdir}/usr/share/fish/vendor_completions.d/{{ .ProjectName }}.fish" 158 | # man pages 159 | install -Dm644 "./manpages/{{ .ProjectName }}.1.gz" "${pkgdir}/usr/share/man/man1/{{ .ProjectName }}.1.gz" 160 | # readme 161 | mkdir -pv "${pkgdir}/usr/share/doc/{{ .ProjectName }}/" 162 | install -Dm644 README* "${pkgdir}/usr/share/doc/{{ .ProjectName }}/" 163 | 164 | nix: 165 | - repository: 166 | owner: "{{ .Var.brew_owner }}" 167 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 168 | name: nur 169 | homepage: "{{ .Var.homepage }}" 170 | description: "{{ .Var.description }}" 171 | license: mit 172 | extra_install: |- 173 | installManPage ./manpages/{{.ProjectName}}.1.gz 174 | installShellCompletion ./completions/* 175 | 176 | winget: 177 | - publisher: charmbracelet 178 | license: MIT 179 | copyright: Charmbracelet, Inc 180 | homepage: "{{ .Var.homepage }}" 181 | short_description: "{{ .Var.description }}" 182 | repository: 183 | owner: "{{ .Var.brew_owner }}" 184 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 185 | name: winget-pkgs 186 | branch: "{{.ProjectName}}-{{.Version}}" 187 | pull_request: 188 | enabled: true 189 | draft: false 190 | check_boxes: true 191 | base: 192 | owner: microsoft 193 | name: winget-pkgs 194 | branch: master 195 | 196 | checksum: 197 | name_template: "checksums.txt" 198 | 199 | source: 200 | enabled: true 201 | 202 | sboms: 203 | - artifacts: archive 204 | - id: source 205 | artifacts: source 206 | 207 | snapshot: 208 | version_template: "{{ incpatch .Version }}-snapshot" 209 | 210 | nightly: 211 | version_template: "{{ incpatch .Version }}-devel" 212 | 213 | changelog: 214 | sort: asc 215 | use: github 216 | filters: 217 | exclude: 218 | - "^test:" 219 | - "^chore" 220 | - "merge conflict" 221 | - Merge pull request 222 | - Merge remote-tracking branch 223 | - Merge branch 224 | - go mod tidy 225 | groups: 226 | - title: Dependency updates 227 | regexp: "^.*\\(deps\\)*:+.*$" 228 | order: 300 229 | - title: "New Features" 230 | regexp: "^.*feat[(\\w)]*:+.*$" 231 | order: 100 232 | - title: "Bug fixes" 233 | regexp: "^.*fix[(\\w)]*:+.*$" 234 | order: 200 235 | - title: "Documentation updates" 236 | regexp: "^.*docs[(\\w)]*:+.*$" 237 | order: 400 238 | - title: Other work 239 | order: 9999 240 | 241 | signs: 242 | - cmd: cosign 243 | certificate: "${artifact}.pem" 244 | args: 245 | - sign-blob 246 | - "--output-certificate=${certificate}" 247 | - "--output-signature=${signature}" 248 | - "${artifact}" 249 | - "--yes" 250 | artifacts: checksum 251 | output: true 252 | 253 | git: 254 | tag_sort: semver 255 | 256 | release: 257 | prerelease: auto 258 | footer: 259 | from_url: 260 | url: https://raw.githubusercontent.com/charmbracelet/meta/main/footer.md 261 | -------------------------------------------------------------------------------- /goreleaser-simple.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json 2 | 3 | version: 2 4 | variables: 5 | main: "" 6 | binary_name: "" 7 | description: "" 8 | maintainer: "" 9 | homepage: "https://charm.sh/" 10 | brew_commit_author_name: "" 11 | brew_commit_author_email: "" 12 | brew_owner: charmbracelet 13 | aur_project_name: "" 14 | 15 | includes: 16 | - from_url: 17 | url: charmbracelet/meta/main/notarize.yaml 18 | 19 | gomod: 20 | proxy: true 21 | 22 | builds: 23 | - binary: "{{ with .Var.binary_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}" 24 | env: 25 | - CGO_ENABLED=0 26 | main: "{{ with .Var.main }}{{ . }}{{ else }}.{{ end }}" 27 | ldflags: -s -w -X main.Version=v{{ .Version }} -X main.CommitSHA={{ .Commit }} -X main.CommitDate={{ .CommitDate }} 28 | goos: 29 | - linux 30 | - darwin 31 | - windows 32 | - freebsd 33 | - openbsd 34 | - netbsd 35 | goarch: 36 | - amd64 37 | - arm64 38 | - "386" 39 | - arm 40 | goarm: 41 | - "7" 42 | ignore: 43 | - goos: windows 44 | goarch: arm64 45 | - goos: windows 46 | goarm: "7" 47 | 48 | archives: 49 | - format_overrides: 50 | - goos: windows 51 | formats: zip 52 | name_template: >- 53 | {{ .ProjectName }}_ 54 | {{- .Version }}_ 55 | {{- title .Os }}_ 56 | {{- if eq .Arch "amd64" }}x86_64 57 | {{- else if eq .Arch "386" }}i386 58 | {{- else }}{{ .Arch }}{{ end }} 59 | wrap_in_directory: true 60 | files: 61 | - README* 62 | - LICENSE* 63 | 64 | nfpms: 65 | - vendor: charmbracelet 66 | homepage: "{{ .Var.homepage }}" 67 | maintainer: "{{ .Var.maintainer }}" 68 | description: "{{ .Var.description }}" 69 | file_name_template: "{{ .ConventionalFileName }}" 70 | license: MIT 71 | formats: 72 | - apk 73 | - deb 74 | - rpm 75 | rpm: 76 | signature: 77 | key_file: '{{ if ne (index .Env "GPG_KEY_PATH") "" }}{{ .Env.GPG_KEY_PATH }}{{ else }}{{ end }}' 78 | deb: 79 | signature: 80 | key_file: '{{ if ne (index .Env "GPG_KEY_PATH") "" }}{{ .Env.GPG_KEY_PATH }}{{ else }}{{ end }}' 81 | 82 | furies: 83 | - account: "{{ with .Env.FURY_TOKEN }}charmcli{{ else }}{{ end }}" 84 | secret_name: FURY_TOKEN 85 | 86 | brews: 87 | - repository: 88 | owner: "{{ .Var.brew_owner }}" 89 | name: homebrew-tap 90 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 91 | commit_author: 92 | name: "{{ .Var.brew_commit_author_name }}" 93 | email: "{{ .Var.brew_commit_author_email }}" 94 | homepage: "{{ .Var.homepage }}" 95 | description: "{{ .Var.description }}" 96 | 97 | scoops: 98 | - repository: 99 | owner: "{{ .Var.brew_owner }}" 100 | name: scoop-bucket 101 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 102 | commit_author: 103 | name: "{{ .Var.brew_commit_author_name }}" 104 | email: "{{ .Var.brew_commit_author_email }}" 105 | homepage: "{{ .Var.homepage }}" 106 | description: "{{ .Var.description }}" 107 | license: MIT 108 | 109 | aurs: 110 | - maintainers: ["{{ .Var.maintainer }}"] 111 | description: "{{ .Var.description }}" 112 | name: "{{ with .Var.aur_project_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}-bin" 113 | homepage: "{{ .Var.homepage }}" 114 | license: MIT 115 | private_key: "{{ .Env.AUR_KEY }}" 116 | git_url: "ssh://aur@aur.archlinux.org/{{ with .Var.aur_project_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}-bin.git" 117 | package: |- 118 | cd "${srcdir}/{{ .ProjectName }}_${pkgver}_Linux_${CARCH}" 119 | # bin 120 | install -Dm755 "./{{ .ProjectName }}" "${pkgdir}/usr/bin/{{ .ProjectName }}" 121 | # license 122 | mkdir -p "${pkgdir}/usr/share/licenses/{{ .ProjectName }}/" 123 | install -Dm644 ./LICENSE* "${pkgdir}/usr/share/licenses/{{ .ProjectName }}/" 124 | # readme 125 | mkdir -pv "${pkgdir}/usr/share/doc/{{ .ProjectName }}/" 126 | install -Dm644 README* "${pkgdir}/usr/share/doc/{{ .ProjectName }}/" 127 | 128 | nix: 129 | - repository: 130 | owner: "{{ .Var.brew_owner }}" 131 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 132 | name: nur 133 | homepage: "{{ .Var.homepage }}" 134 | description: "{{ .Var.description }}" 135 | license: mit 136 | 137 | winget: 138 | - publisher: charmbracelet 139 | license: MIT 140 | copyright: Charmbracelet, Inc 141 | homepage: "{{ .Var.homepage }}" 142 | short_description: "{{ .Var.description }}" 143 | repository: 144 | owner: "{{ .Var.brew_owner }}" 145 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 146 | name: winget-pkgs 147 | branch: "{{.ProjectName}}-{{.Version}}" 148 | pull_request: 149 | enabled: true 150 | draft: false 151 | check_boxes: true 152 | base: 153 | owner: microsoft 154 | name: winget-pkgs 155 | branch: master 156 | checksum: 157 | name_template: "checksums.txt" 158 | 159 | source: 160 | enabled: true 161 | 162 | sboms: 163 | - artifacts: archive 164 | - id: source 165 | artifacts: source 166 | 167 | snapshot: 168 | version_template: "{{ incpatch .Version }}-snapshot" 169 | 170 | nightly: 171 | version_template: "{{ incpatch .Version }}-devel" 172 | 173 | changelog: 174 | sort: asc 175 | use: github 176 | filters: 177 | exclude: 178 | - "^test:" 179 | - "^chore" 180 | - "merge conflict" 181 | - Merge pull request 182 | - Merge remote-tracking branch 183 | - Merge branch 184 | - go mod tidy 185 | groups: 186 | - title: Dependency updates 187 | regexp: "^.*\\(deps\\)*:+.*$" 188 | order: 300 189 | - title: "New Features" 190 | regexp: "^.*feat[(\\w)]*:+.*$" 191 | order: 100 192 | - title: "Bug fixes" 193 | regexp: "^.*fix[(\\w)]*:+.*$" 194 | order: 200 195 | - title: "Documentation updates" 196 | regexp: "^.*docs[(\\w)]*:+.*$" 197 | order: 400 198 | - title: Other work 199 | order: 9999 200 | 201 | signs: 202 | - cmd: cosign 203 | certificate: "${artifact}.pem" 204 | args: 205 | - sign-blob 206 | - "--output-certificate=${certificate}" 207 | - "--output-signature=${signature}" 208 | - "${artifact}" 209 | - "--yes" 210 | artifacts: checksum 211 | output: true 212 | 213 | git: 214 | tag_sort: semver 215 | 216 | release: 217 | prerelease: auto 218 | footer: 219 | from_url: 220 | url: https://raw.githubusercontent.com/charmbracelet/meta/main/footer.md 221 | -------------------------------------------------------------------------------- /goreleaser-soft-serve.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json 2 | 3 | version: 2 4 | variables: 5 | main: "" 6 | binary_name: "" 7 | description: "" 8 | github_url: "" 9 | maintainer: "" 10 | homepage: "https://charm.sh/" 11 | brew_commit_author_name: "" 12 | brew_commit_author_email: "" 13 | brew_owner: charmbracelet 14 | docker_io_registry_owner: charmcli 15 | ghcr_io_registry_owner: charmbracelet 16 | aur_project_name: "" 17 | 18 | includes: 19 | - from_url: 20 | url: charmbracelet/meta/main/notarize.yaml 21 | 22 | before: 23 | hooks: 24 | - go mod tidy 25 | - rm -rf completions 26 | - mkdir completions 27 | - rm -rf manpages 28 | - mkdir manpages 29 | - sh -c 'go run {{ with .Var.main }}{{ . }}{{ else }}.{{ end }} completion "bash" >./completions/{{ .ProjectName }}.bash' 30 | - sh -c 'go run {{ with .Var.main }}{{ . }}{{ else }}.{{ end }} completion "zsh" >./completions/{{ .ProjectName }}.zsh' 31 | - sh -c 'go run {{ with .Var.main }}{{ . }}{{ else }}.{{ end }} completion "fish" >./completions/{{ .ProjectName }}.fish' 32 | - sh -c 'go run {{ with .Var.main }}{{ . }}{{ else }}.{{ end }} man | gzip -c >./manpages/{{ .ProjectName }}.1.gz' 33 | 34 | gomod: 35 | proxy: true 36 | 37 | builds: 38 | - binary: "{{ with .Var.binary_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}" 39 | env: 40 | - CGO_ENABLED=0 41 | main: "{{ with .Var.main }}{{ . }}{{ else }}.{{ end }}" 42 | ldflags: -s -w -X main.Version=v{{ .Version }} -X main.CommitSHA={{ .Commit }} -X main.CommitDate={{ .CommitDate }} 43 | goos: 44 | - linux 45 | - darwin 46 | - windows 47 | - freebsd 48 | goarch: 49 | - amd64 50 | - arm64 51 | - "386" 52 | - arm 53 | goarm: 54 | - "7" 55 | ignore: 56 | - goos: windows 57 | goarch: arm64 58 | - goos: windows 59 | goarch: "386" 60 | - goos: windows 61 | goarm: "7" 62 | 63 | archives: 64 | - format_overrides: 65 | - goos: windows 66 | formats: zip 67 | name_template: >- 68 | {{ .ProjectName }}_ 69 | {{- .Version }}_ 70 | {{- title .Os }}_ 71 | {{- if eq .Arch "amd64" }}x86_64 72 | {{- else if eq .Arch "386" }}i386 73 | {{- else }}{{ .Arch }}{{ end }} 74 | wrap_in_directory: true 75 | files: 76 | - README* 77 | - LICENSE* 78 | - manpages/* 79 | - completions/* 80 | 81 | nfpms: 82 | - vendor: charmbracelet 83 | homepage: "{{ .Var.homepage }}" 84 | maintainer: "{{ .Var.maintainer }}" 85 | description: "{{ .Var.description }}" 86 | file_name_template: "{{ .ConventionalFileName }}" 87 | license: MIT 88 | formats: 89 | - apk 90 | - deb 91 | - rpm 92 | contents: 93 | - src: ./completions/{{ .ProjectName }}.bash 94 | dst: /etc/bash_completion.d/{{ .ProjectName }} 95 | - src: ./completions/{{ .ProjectName }}.fish 96 | dst: /usr/share/fish/vendor_completions.d/{{ .ProjectName }}.fish 97 | - src: ./completions/{{ .ProjectName }}.zsh 98 | dst: /usr/share/zsh/site-functions/_{{ .ProjectName }} 99 | - src: ./manpages/{{ .ProjectName }}.1.gz 100 | dst: /usr/share/man/man1/{{ .ProjectName }}.1.gz 101 | - src: ./.nfpm/soft-serve.service 102 | dst: /usr/lib/systemd/system/soft-serve.service 103 | - src: ./.nfpm/soft-serve.conf 104 | dst: /etc/soft-serve.conf 105 | - src: ./.nfpm/sysusers.conf 106 | dst: /usr/lib/sysusers.d/soft-serve.conf 107 | - src: ./.nfpm/tmpfiles.conf 108 | dst: /usr/lib/tmpfiles.d/soft-serve.conf 109 | scripts: 110 | postinstall: ./.nfpm/postinstall.sh 111 | postremove: ./.nfpm/postremove.sh 112 | dependencies: 113 | - git 114 | - bash 115 | rpm: 116 | signature: 117 | key_file: '{{ if ne (index .Env "GPG_KEY_PATH") "" }}{{ .Env.GPG_KEY_PATH }}{{ else }}{{ end }}' 118 | deb: 119 | signature: 120 | key_file: '{{ if ne (index .Env "GPG_KEY_PATH") "" }}{{ .Env.GPG_KEY_PATH }}{{ else }}{{ end }}' 121 | 122 | furies: 123 | - account: "{{ with .Env.FURY_TOKEN }}charmcli{{ else }}{{ end }}" 124 | secret_name: FURY_TOKEN 125 | 126 | brews: 127 | - repository: 128 | owner: "{{ .Var.brew_owner }}" 129 | name: homebrew-tap 130 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 131 | commit_author: 132 | name: "{{ .Var.brew_commit_author_name }}" 133 | email: "{{ .Var.brew_commit_author_email }}" 134 | homepage: "{{ .Var.homepage }}" 135 | description: "{{ .Var.description }}" 136 | dependencies: 137 | - name: git 138 | - name: bash 139 | install: |- 140 | bin.install "{{ with .Var.binary_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}" 141 | bash_completion.install "completions/{{ .ProjectName }}.bash" => "{{ .ProjectName }}" 142 | zsh_completion.install "completions/{{ .ProjectName }}.zsh" => "_{{ .ProjectName }}" 143 | fish_completion.install "completions/{{ .ProjectName }}.fish" 144 | man1.install "manpages/{{ .ProjectName }}.1.gz" 145 | 146 | scoops: 147 | - repository: 148 | owner: "{{ .Var.brew_owner }}" 149 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 150 | name: scoop-bucket 151 | commit_author: 152 | name: "{{ .Var.brew_commit_author_name }}" 153 | email: "{{ .Var.brew_commit_author_email }}" 154 | homepage: "{{ .Var.homepage }}" 155 | description: "{{ .Var.description }}" 156 | license: MIT 157 | depends: 158 | - git 159 | 160 | aurs: 161 | - maintainers: ["{{ .Var.maintainer }}"] 162 | description: "{{ .Var.description }}" 163 | name: "{{ with .Var.aur_project_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}-bin" 164 | homepage: "{{ .Var.homepage }}" 165 | license: MIT 166 | private_key: "{{ .Env.AUR_KEY }}" 167 | git_url: "ssh://aur@aur.archlinux.org/{{ with .Var.aur_project_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}-bin.git" 168 | depends: 169 | - git 170 | - bash 171 | package: |- 172 | cd "${srcdir}/{{ .ProjectName }}_${pkgver}_Linux_${CARCH}" 173 | # bin 174 | install -Dm755 "./{{ .ProjectName }}" "${pkgdir}/usr/bin/{{ .ProjectName }}" 175 | # license 176 | mkdir -p "${pkgdir}/usr/share/licenses/{{ .ProjectName }}/" 177 | install -Dm644 ./LICENSE* "${pkgdir}/usr/share/licenses/{{ .ProjectName }}/" 178 | # completions 179 | mkdir -p "${pkgdir}/usr/share/bash-completion/completions/" 180 | mkdir -p "${pkgdir}/usr/share/zsh/site-functions/" 181 | mkdir -p "${pkgdir}/usr/share/fish/vendor_completions.d/" 182 | install -Dm644 "./completions/{{ .ProjectName }}.bash" "${pkgdir}/usr/share/bash-completion/completions/{{ .ProjectName }}" 183 | install -Dm644 "./completions/{{ .ProjectName }}.zsh" "${pkgdir}/usr/share/zsh/site-functions/_{{ .ProjectName }}" 184 | install -Dm644 "./completions/{{ .ProjectName }}.fish" "${pkgdir}/usr/share/fish/vendor_completions.d/{{ .ProjectName }}.fish" 185 | # man pages 186 | install -Dm644 "./manpages/{{ .ProjectName }}.1.gz" "${pkgdir}/usr/share/man/man1/{{ .ProjectName }}.1.gz" 187 | # readme 188 | mkdir -pv "${pkgdir}/usr/share/doc/{{ .ProjectName }}/" 189 | install -Dm644 README* "${pkgdir}/usr/share/doc/{{ .ProjectName }}/" 190 | 191 | nix: 192 | - repository: 193 | owner: "{{ .Var.brew_owner }}" 194 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 195 | name: nur 196 | homepage: "{{ .Var.homepage }}" 197 | description: "{{ .Var.description }}" 198 | license: mit 199 | extra_install: |- 200 | installManPage ./manpages/{{.ProjectName}}.1.gz 201 | installShellCompletion ./completions/* 202 | 203 | winget: 204 | - publisher: charmbracelet 205 | license: MIT 206 | copyright: Charmbracelet, Inc 207 | homepage: "{{ .Var.homepage }}" 208 | short_description: "{{ .Var.description }}" 209 | repository: 210 | owner: "{{ .Var.brew_owner }}" 211 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 212 | name: winget-pkgs 213 | branch: "{{.ProjectName}}-{{.Version}}" 214 | pull_request: 215 | enabled: true 216 | draft: false 217 | check_boxes: true 218 | base: 219 | owner: microsoft 220 | name: winget-pkgs 221 | branch: master 222 | checksum: 223 | name_template: "checksums.txt" 224 | 225 | source: 226 | enabled: true 227 | 228 | sboms: 229 | - artifacts: archive 230 | - id: source 231 | artifacts: source 232 | 233 | snapshot: 234 | version_template: "{{ incpatch .Version }}-snapshot" 235 | 236 | nightly: 237 | version_template: "{{ incpatch .Version }}-devel" 238 | 239 | changelog: 240 | sort: asc 241 | use: github 242 | filters: 243 | exclude: 244 | - "^test:" 245 | - "^chore" 246 | - "merge conflict" 247 | - Merge pull request 248 | - Merge remote-tracking branch 249 | - Merge branch 250 | - go mod tidy 251 | groups: 252 | - title: Dependency updates 253 | regexp: "^.*\\(deps\\)*:+.*$" 254 | order: 300 255 | - title: "New Features" 256 | regexp: "^.*feat[(\\w)]*:+.*$" 257 | order: 100 258 | - title: "Bug fixes" 259 | regexp: "^.*fix[(\\w)]*:+.*$" 260 | order: 200 261 | - title: "Documentation updates" 262 | regexp: "^.*docs[(\\w)]*:+.*$" 263 | order: 400 264 | - title: Other work 265 | order: 9999 266 | 267 | signs: 268 | - cmd: cosign 269 | certificate: "${artifact}.pem" 270 | args: 271 | - sign-blob 272 | - "--output-certificate=${certificate}" 273 | - "--output-signature=${signature}" 274 | - "${artifact}" 275 | - "--yes" 276 | artifacts: checksum 277 | output: true 278 | 279 | dockers: 280 | - image_templates: 281 | - "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64{{ end }}" 282 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 283 | goarch: amd64 284 | build_flag_templates: 285 | - --platform=linux/amd64 286 | - --label=org.opencontainers.image.title={{ .ProjectName }} 287 | - --label=org.opencontainers.image.description={{ .Var.description }} 288 | - --label=org.opencontainers.image.source={{ .GitURL }} 289 | - --label=org.opencontainers.image.version=v{{ .Version }} 290 | - --label=org.opencontainers.image.created={{ .Date }} 291 | - --label=org.opencontainers.image.revision={{ .FullCommit }} 292 | - --label=org.opencontainers.image.licenses=MIT 293 | dockerfile: Dockerfile 294 | use: buildx 295 | - image_templates: 296 | - "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64{{ end }}" 297 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 298 | goarch: arm64 299 | build_flag_templates: 300 | - --platform=linux/arm64 301 | - --label=org.opencontainers.image.title={{ .ProjectName }} 302 | - --label=org.opencontainers.image.description={{ .Var.description }} 303 | - --label=org.opencontainers.image.source={{ .GitURL }} 304 | - --label=org.opencontainers.image.version=v{{ .Version }} 305 | - --label=org.opencontainers.image.created={{ .Date }} 306 | - --label=org.opencontainers.image.revision={{ .FullCommit }} 307 | - --label=org.opencontainers.image.licenses=MIT 308 | dockerfile: Dockerfile 309 | use: buildx 310 | - image_templates: 311 | - "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7{{ end }}" 312 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 313 | goarch: arm 314 | goarm: "7" 315 | build_flag_templates: 316 | - --platform=linux/arm/v7 317 | - --label=org.opencontainers.image.title={{ .ProjectName }} 318 | - --label=org.opencontainers.image.description={{ .Var.description }} 319 | - --label=org.opencontainers.image.source={{ .GitURL }} 320 | - --label=org.opencontainers.image.version=v{{ .Version }} 321 | - --label=org.opencontainers.image.created={{ .Date }} 322 | - --label=org.opencontainers.image.revision={{ .FullCommit }} 323 | - --label=org.opencontainers.image.licenses=MIT 324 | dockerfile: Dockerfile 325 | use: buildx 326 | 327 | docker_manifests: 328 | - name_template: "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:latest{{ end }}" 329 | image_templates: 330 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 331 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 332 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 333 | - name_template: "{{ if not .IsNightly }}ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:latest{{ end }}" 334 | image_templates: 335 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 336 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 337 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 338 | - name_template: "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Major }}.{{ .Minor }}{{ end }}" 339 | image_templates: 340 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 341 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 342 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 343 | - name_template: "{{ if not .IsNightly }}ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Major }}.{{ .Minor }}{{ end }}" 344 | image_templates: 345 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 346 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 347 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 348 | - name_template: "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}{{ end }}" 349 | image_templates: 350 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 351 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 352 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 353 | - name_template: "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}" 354 | image_templates: 355 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 356 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 357 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 358 | 359 | docker_signs: 360 | - cmd: cosign 361 | artifacts: manifests 362 | output: true 363 | args: 364 | - "sign" 365 | - "${artifact}" 366 | - "--yes" 367 | 368 | git: 369 | tag_sort: semver 370 | 371 | release: 372 | prerelease: auto 373 | footer: 374 | from_url: 375 | url: https://raw.githubusercontent.com/charmbracelet/meta/main/footer.md 376 | -------------------------------------------------------------------------------- /goreleaser-vhs.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json 2 | 3 | version: 2 4 | variables: 5 | main: "" 6 | binary_name: "" 7 | description: "" 8 | maintainer: "" 9 | homepage: "https://charm.sh/" 10 | brew_commit_author_name: "" 11 | brew_commit_author_email: "" 12 | brew_owner: charmbracelet 13 | docker_io_registry_owner: charmcli 14 | ghcr_io_registry_owner: charmbracelet 15 | aur_project_name: "" 16 | 17 | includes: 18 | - from_url: 19 | url: charmbracelet/meta/main/notarize.yaml 20 | 21 | before: 22 | hooks: 23 | - go mod tidy 24 | - rm -rf completions 25 | - mkdir completions 26 | - rm -rf manpages 27 | - mkdir manpages 28 | - sh -c 'go run {{ with .Var.main }}{{ . }}{{ else }}.{{ end }} completion "bash" >./completions/{{ .ProjectName }}.bash' 29 | - sh -c 'go run {{ with .Var.main }}{{ . }}{{ else }}.{{ end }} completion "zsh" >./completions/{{ .ProjectName }}.zsh' 30 | - sh -c 'go run {{ with .Var.main }}{{ . }}{{ else }}.{{ end }} completion "fish" >./completions/{{ .ProjectName }}.fish' 31 | - sh -c 'go run {{ with .Var.main }}{{ . }}{{ else }}.{{ end }} man | gzip -c >./manpages/{{ .ProjectName }}.1.gz' 32 | 33 | gomod: 34 | proxy: true 35 | 36 | builds: 37 | - binary: "{{ with .Var.binary_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}" 38 | env: 39 | - CGO_ENABLED=0 40 | main: "{{ with .Var.main }}{{ . }}{{ else }}.{{ end }}" 41 | ldflags: -s -w -X main.Version=v{{ .Version }} -X main.CommitSHA={{ .Commit }} -X main.CommitDate={{ .CommitDate }} 42 | goos: 43 | - linux 44 | - darwin 45 | - windows 46 | goarch: 47 | - amd64 48 | - arm64 49 | - "386" 50 | - arm 51 | goarm: 52 | - "7" 53 | ignore: 54 | - goos: windows 55 | goarch: arm64 56 | - goos: windows 57 | goarm: "7" 58 | 59 | archives: 60 | - format_overrides: 61 | - goos: windows 62 | formats: zip 63 | name_template: >- 64 | {{ .ProjectName }}_ 65 | {{- .Version }}_ 66 | {{- title .Os }}_ 67 | {{- if eq .Arch "amd64" }}x86_64 68 | {{- else if eq .Arch "386" }}i386 69 | {{- else }}{{ .Arch }}{{ end }} 70 | wrap_in_directory: true 71 | files: 72 | - README* 73 | - LICENSE* 74 | - manpages/* 75 | - completions/* 76 | 77 | nfpms: 78 | - vendor: charmbracelet 79 | homepage: "{{ .Var.homepage }}" 80 | maintainer: "{{ .Var.maintainer }}" 81 | description: "{{ .Var.description }}" 82 | file_name_template: "{{ .ConventionalFileName }}" 83 | license: MIT 84 | formats: 85 | - apk 86 | - deb 87 | - rpm 88 | contents: 89 | - src: ./completions/{{ .ProjectName }}.bash 90 | dst: /etc/bash_completion.d/{{ .ProjectName }} 91 | - src: ./completions/{{ .ProjectName }}.fish 92 | dst: /usr/share/fish/vendor_completions.d/{{ .ProjectName }}.fish 93 | - src: ./completions/{{ .ProjectName }}.zsh 94 | dst: /usr/share/zsh/site-functions/_{{ .ProjectName }} 95 | - src: ./manpages/{{ .ProjectName }}.1.gz 96 | dst: /usr/share/man/man1/{{ .ProjectName }}.1.gz 97 | dependencies: 98 | - ffmpeg 99 | # - ttyd # not available on debian/rhel repositories 100 | rpm: 101 | signature: 102 | key_file: '{{ if ne (index .Env "GPG_KEY_PATH") "" }}{{ .Env.GPG_KEY_PATH }}{{ else }}{{ end }}' 103 | deb: 104 | signature: 105 | key_file: '{{ if ne (index .Env "GPG_KEY_PATH") "" }}{{ .Env.GPG_KEY_PATH }}{{ else }}{{ end }}' 106 | 107 | furies: 108 | - account: "{{ with .Env.FURY_TOKEN }}charmcli{{ else }}{{ end }}" 109 | secret_name: FURY_TOKEN 110 | 111 | brews: 112 | - repository: 113 | owner: "{{ .Var.brew_owner }}" 114 | name: homebrew-tap 115 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 116 | commit_author: 117 | name: "{{ .Var.brew_commit_author_name }}" 118 | email: "{{ .Var.brew_commit_author_email }}" 119 | homepage: "{{ .Var.homepage }}" 120 | description: "{{ .Var.description }}" 121 | dependencies: 122 | - name: ffmpeg 123 | - name: ttyd 124 | install: |- 125 | bin.install "{{ with .Var.binary_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}" 126 | bash_completion.install "completions/{{ .ProjectName }}.bash" => "{{ .ProjectName }}" 127 | zsh_completion.install "completions/{{ .ProjectName }}.zsh" => "_{{ .ProjectName }}" 128 | fish_completion.install "completions/{{ .ProjectName }}.fish" 129 | man1.install "manpages/{{ .ProjectName }}.1.gz" 130 | 131 | scoops: 132 | - repository: 133 | owner: "{{ .Var.brew_owner }}" 134 | name: scoop-bucket 135 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 136 | commit_author: 137 | name: "{{ .Var.brew_commit_author_name }}" 138 | email: "{{ .Var.brew_commit_author_email }}" 139 | homepage: "{{ .Var.homepage }}" 140 | description: "{{ .Var.description }}" 141 | license: MIT 142 | 143 | nix: 144 | - repository: 145 | owner: "{{ .Var.brew_owner }}" 146 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 147 | name: nur 148 | homepage: "{{ .Var.homepage }}" 149 | description: "{{ .Var.description }}" 150 | license: mit 151 | path: pkgs/{{.ProjectName}}/default.nix 152 | dependencies: 153 | - ffmpeg 154 | - ttyd 155 | - name: chromium 156 | os: linux 157 | extra_install: |- 158 | installManPage ./manpages/{{.ProjectName}}.1.gz 159 | installShellCompletion ./completions/* 160 | 161 | winget: 162 | - publisher: charmbracelet 163 | license: MIT 164 | copyright: Charmbracelet, Inc 165 | homepage: "{{ .Var.homepage }}" 166 | short_description: "{{ .Var.description }}" 167 | repository: 168 | owner: "{{ .Var.brew_owner }}" 169 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 170 | name: winget-pkgs 171 | branch: "{{.ProjectName}}-{{.Version}}" 172 | pull_request: 173 | enabled: true 174 | draft: false 175 | check_boxes: true 176 | base: 177 | owner: microsoft 178 | name: winget-pkgs 179 | branch: master 180 | 181 | aurs: 182 | - maintainers: ["{{ .Var.maintainer }}"] 183 | description: "{{ .Var.description }}" 184 | name: "{{ with .Var.aur_project_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}-bin" 185 | homepage: "{{ .Var.homepage }}" 186 | license: MIT 187 | private_key: "{{ .Env.AUR_KEY }}" 188 | git_url: "ssh://aur@aur.archlinux.org/{{ with .Var.aur_project_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}-bin.git" 189 | depends: 190 | - ffmpeg 191 | - ttyd 192 | package: |- 193 | cd "${srcdir}/{{ .ProjectName }}_${pkgver}_Linux_${CARCH}" 194 | # bin 195 | install -Dm755 "./{{ .ProjectName }}" "${pkgdir}/usr/bin/{{ .ProjectName }}" 196 | # license 197 | mkdir -p "${pkgdir}/usr/share/licenses/{{ .ProjectName }}/" 198 | install -Dm644 ./LICENSE* "${pkgdir}/usr/share/licenses/{{ .ProjectName }}/" 199 | # completions 200 | mkdir -p "${pkgdir}/usr/share/bash-completion/completions/" 201 | mkdir -p "${pkgdir}/usr/share/zsh/site-functions/" 202 | mkdir -p "${pkgdir}/usr/share/fish/vendor_completions.d/" 203 | install -Dm644 "./completions/{{ .ProjectName }}.bash" "${pkgdir}/usr/share/bash-completion/completions/{{ .ProjectName }}" 204 | install -Dm644 "./completions/{{ .ProjectName }}.zsh" "${pkgdir}/usr/share/zsh/site-functions/_{{ .ProjectName }}" 205 | install -Dm644 "./completions/{{ .ProjectName }}.fish" "${pkgdir}/usr/share/fish/vendor_completions.d/{{ .ProjectName }}.fish" 206 | # man pages 207 | install -Dm644 "./manpages/{{ .ProjectName }}.1.gz" "${pkgdir}/usr/share/man/man1/{{ .ProjectName }}.1.gz" 208 | # readme 209 | mkdir -pv "${pkgdir}/usr/share/doc/{{ .ProjectName }}/" 210 | install -Dm644 README* "${pkgdir}/usr/share/doc/{{ .ProjectName }}/" 211 | 212 | checksum: 213 | name_template: "checksums.txt" 214 | 215 | source: 216 | enabled: true 217 | 218 | sboms: 219 | - artifacts: archive 220 | - id: source 221 | artifacts: source 222 | 223 | snapshot: 224 | version_template: "{{ incpatch .Version }}-snapshot" 225 | 226 | nightly: 227 | version_template: "{{ incpatch .Version }}-devel" 228 | 229 | changelog: 230 | sort: asc 231 | use: github 232 | filters: 233 | exclude: 234 | - "^test:" 235 | - "^chore" 236 | - "merge conflict" 237 | - Merge pull request 238 | - Merge remote-tracking branch 239 | - Merge branch 240 | - go mod tidy 241 | groups: 242 | - title: Dependency updates 243 | regexp: "^.*\\(deps\\)*:+.*$" 244 | order: 300 245 | - title: "New Features" 246 | regexp: "^.*feat[(\\w)]*:+.*$" 247 | order: 100 248 | - title: "Bug fixes" 249 | regexp: "^.*fix[(\\w)]*:+.*$" 250 | order: 200 251 | - title: "Documentation updates" 252 | regexp: "^.*docs[(\\w)]*:+.*$" 253 | order: 400 254 | - title: Other work 255 | order: 9999 256 | 257 | signs: 258 | - cmd: cosign 259 | certificate: "${artifact}.pem" 260 | args: 261 | - sign-blob 262 | - "--output-certificate=${certificate}" 263 | - "--output-signature=${signature}" 264 | - "${artifact}" 265 | - "--yes" 266 | artifacts: checksum 267 | output: true 268 | 269 | dockers: 270 | - image_templates: 271 | - "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64{{ end }}" 272 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 273 | goarch: amd64 274 | build_flag_templates: 275 | - --platform=linux/amd64 276 | - --label=org.opencontainers.image.title={{ .ProjectName }} 277 | - --label=org.opencontainers.image.description={{ .Var.description }} 278 | - --label=org.opencontainers.image.source={{ .GitURL }} 279 | - --label=org.opencontainers.image.version=v{{ .Version }} 280 | - --label=org.opencontainers.image.created={{ .Date }} 281 | - --label=org.opencontainers.image.revision={{ .FullCommit }} 282 | - --label=org.opencontainers.image.licenses=MIT 283 | dockerfile: Dockerfile 284 | use: buildx 285 | - image_templates: 286 | - "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64{{ end }}" 287 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 288 | goarch: arm64 289 | build_flag_templates: 290 | - --platform=linux/arm64 291 | - --label=org.opencontainers.image.title={{ .ProjectName }} 292 | - --label=org.opencontainers.image.description={{ .Var.description }} 293 | - --label=org.opencontainers.image.source={{ .GitURL }} 294 | - --label=org.opencontainers.image.version=v{{ .Version }} 295 | - --label=org.opencontainers.image.created={{ .Date }} 296 | - --label=org.opencontainers.image.revision={{ .FullCommit }} 297 | - --label=org.opencontainers.image.licenses=MIT 298 | dockerfile: Dockerfile 299 | use: buildx 300 | 301 | docker_manifests: 302 | - name_template: "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:latest{{ end }}" 303 | image_templates: 304 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 305 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 306 | - name_template: "{{ if not .IsNightly }}ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:latest{{ end }}" 307 | image_templates: 308 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 309 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 310 | - name_template: "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Major }}.{{ .Minor }}{{ end }}" 311 | image_templates: 312 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 313 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 314 | - name_template: "{{ if not .IsNightly }}ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Major }}.{{ .Minor }}{{ end }}" 315 | image_templates: 316 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 317 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 318 | - name_template: "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}{{ end }}" 319 | image_templates: 320 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 321 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 322 | - name_template: "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}" 323 | image_templates: 324 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 325 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 326 | 327 | docker_signs: 328 | - cmd: cosign 329 | artifacts: manifests 330 | output: true 331 | args: 332 | - "sign" 333 | - "${artifact}" 334 | - "--yes" 335 | 336 | git: 337 | tag_sort: semver 338 | 339 | release: 340 | prerelease: auto 341 | footer: 342 | from_url: 343 | url: https://raw.githubusercontent.com/charmbracelet/meta/main/footer.md 344 | -------------------------------------------------------------------------------- /goreleaser.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json 2 | 3 | version: 2 4 | variables: 5 | main: "" 6 | binary_name: "" 7 | description: "" 8 | github_url: "" 9 | maintainer: "" 10 | homepage: "https://charm.sh/" 11 | brew_commit_author_name: "" 12 | brew_commit_author_email: "" 13 | brew_owner: charmbracelet 14 | docker_io_registry_owner: charmcli 15 | ghcr_io_registry_owner: charmbracelet 16 | aur_project_name: "" 17 | 18 | includes: 19 | - from_url: 20 | url: charmbracelet/meta/main/notarize.yaml 21 | 22 | before: 23 | hooks: 24 | - go mod tidy 25 | 26 | gomod: 27 | proxy: true 28 | 29 | builds: 30 | - binary: "{{ with .Var.binary_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}" 31 | env: 32 | - CGO_ENABLED=0 33 | main: "{{ with .Var.main }}{{ . }}{{ else }}.{{ end }}" 34 | ldflags: -s -w -X main.Version=v{{ .Version }} -X main.CommitSHA={{ .Commit }} -X main.CommitDate={{ .CommitDate }} 35 | goos: 36 | - linux 37 | - darwin 38 | - windows 39 | - freebsd 40 | - openbsd 41 | - netbsd 42 | goarch: 43 | - amd64 44 | - arm64 45 | - "386" 46 | - arm 47 | goarm: 48 | - "7" 49 | ignore: 50 | - goos: windows 51 | goarch: arm64 52 | - goos: windows 53 | goarm: "7" 54 | 55 | archives: 56 | - format_overrides: 57 | - goos: windows 58 | formats: zip 59 | name_template: >- 60 | {{ .ProjectName }}_ 61 | {{- .Version }}_ 62 | {{- title .Os }}_ 63 | {{- if eq .Arch "amd64" }}x86_64 64 | {{- else if eq .Arch "386" }}i386 65 | {{- else }}{{ .Arch }}{{ end }} 66 | wrap_in_directory: true 67 | 68 | nfpms: 69 | - vendor: charmbracelet 70 | homepage: "{{ .Var.homepage }}" 71 | maintainer: "{{ .Var.maintainer }}" 72 | description: "{{ .Var.description }}" 73 | file_name_template: "{{ .ConventionalFileName }}" 74 | license: MIT 75 | formats: 76 | - apk 77 | - deb 78 | - rpm 79 | rpm: 80 | signature: 81 | key_file: '{{ if ne (index .Env "GPG_KEY_PATH") "" }}{{ .Env.GPG_KEY_PATH }}{{ else }}{{ end }}' 82 | deb: 83 | signature: 84 | key_file: '{{ if ne (index .Env "GPG_KEY_PATH") "" }}{{ .Env.GPG_KEY_PATH }}{{ else }}{{ end }}' 85 | 86 | furies: 87 | - account: "{{ with .Env.FURY_TOKEN }}charmcli{{ else }}{{ end }}" 88 | secret_name: FURY_TOKEN 89 | 90 | brews: 91 | - repository: 92 | owner: "{{ .Var.brew_owner }}" 93 | name: homebrew-tap 94 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 95 | commit_author: 96 | name: "{{ .Var.brew_commit_author_name }}" 97 | email: "{{ .Var.brew_commit_author_email }}" 98 | homepage: "{{ .Var.homepage }}" 99 | description: "{{ .Var.description }}" 100 | 101 | scoops: 102 | - repository: 103 | owner: "{{ .Var.brew_owner }}" 104 | name: scoop-bucket 105 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 106 | commit_author: 107 | name: "{{ .Var.brew_commit_author_name }}" 108 | email: "{{ .Var.brew_commit_author_email }}" 109 | homepage: "{{ .Var.homepage }}" 110 | description: "{{ .Var.description }}" 111 | license: MIT 112 | 113 | aurs: 114 | - maintainers: ["{{ .Var.maintainer }}"] 115 | description: "{{ .Var.description }}" 116 | name: "{{ with .Var.aur_project_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}-bin" 117 | homepage: "{{ .Var.homepage }}" 118 | license: MIT 119 | private_key: "{{ .Env.AUR_KEY }}" 120 | git_url: "ssh://aur@aur.archlinux.org/{{ with .Var.aur_project_name }}{{ . }}{{ else }}{{ .ProjectName }}{{ end }}-bin.git" 121 | 122 | nix: 123 | - repository: 124 | owner: "{{ .Var.brew_owner }}" 125 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 126 | name: nur 127 | homepage: "{{ .Var.homepage }}" 128 | description: "{{ .Var.description }}" 129 | license: mit 130 | 131 | winget: 132 | - publisher: charmbracelet 133 | license: MIT 134 | copyright: Charmbracelet, Inc 135 | homepage: "{{ .Var.homepage }}" 136 | short_description: "{{ .Var.description }}" 137 | repository: 138 | owner: "{{ .Var.brew_owner }}" 139 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" 140 | name: winget-pkgs 141 | branch: "{{.ProjectName}}-{{.Version}}" 142 | pull_request: 143 | enabled: true 144 | draft: false 145 | check_boxes: true 146 | base: 147 | owner: microsoft 148 | name: winget-pkgs 149 | branch: master 150 | 151 | checksum: 152 | name_template: "checksums.txt" 153 | 154 | source: 155 | enabled: true 156 | 157 | sboms: 158 | - artifacts: archive 159 | - id: source 160 | artifacts: source 161 | 162 | snapshot: 163 | version_template: "{{ incpatch .Version }}-snapshot" 164 | 165 | nightly: 166 | version_template: "{{ incpatch .Version }}-devel" 167 | 168 | changelog: 169 | sort: asc 170 | use: github 171 | filters: 172 | exclude: 173 | - "^test:" 174 | - "^chore" 175 | - "merge conflict" 176 | - Merge pull request 177 | - Merge remote-tracking branch 178 | - Merge branch 179 | - go mod tidy 180 | groups: 181 | - title: Dependency updates 182 | regexp: "^.*\\(deps\\)*:+.*$" 183 | order: 300 184 | - title: "New Features" 185 | regexp: "^.*feat[(\\w)]*:+.*$" 186 | order: 100 187 | - title: "Bug fixes" 188 | regexp: "^.*fix[(\\w)]*:+.*$" 189 | order: 200 190 | - title: "Documentation updates" 191 | regexp: "^.*docs[(\\w)]*:+.*$" 192 | order: 400 193 | - title: Other work 194 | order: 9999 195 | 196 | signs: 197 | - cmd: cosign 198 | certificate: "${artifact}.pem" 199 | args: 200 | - sign-blob 201 | - "--output-certificate=${certificate}" 202 | - "--output-signature=${signature}" 203 | - "${artifact}" 204 | - "--yes" 205 | artifacts: checksum 206 | output: true 207 | 208 | dockers: 209 | - image_templates: 210 | - "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64{{ end }}" 211 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 212 | goarch: amd64 213 | build_flag_templates: 214 | - --platform=linux/amd64 215 | - --label=org.opencontainers.image.title={{ .ProjectName }} 216 | - --label=org.opencontainers.image.description={{ .ProjectName }} 217 | - --label=org.opencontainers.image.source={{ .GitURL }} 218 | - --label=org.opencontainers.image.version=v{{ .Version }} 219 | - --label=org.opencontainers.image.created={{ .Date }} 220 | - --label=org.opencontainers.image.revision={{ .FullCommit }} 221 | - --label=org.opencontainers.image.licenses=MIT 222 | dockerfile: Dockerfile 223 | use: buildx 224 | - image_templates: 225 | - "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64{{ end }}" 226 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 227 | goarch: arm64 228 | build_flag_templates: 229 | - --platform=linux/arm64 230 | - --label=org.opencontainers.image.title={{ .ProjectName }} 231 | - --label=org.opencontainers.image.description={{ .ProjectName }} 232 | - --label=org.opencontainers.image.source={{ .GitURL }} 233 | - --label=org.opencontainers.image.version=v{{ .Version }} 234 | - --label=org.opencontainers.image.created={{ .Date }} 235 | - --label=org.opencontainers.image.revision={{ .FullCommit }} 236 | - --label=org.opencontainers.image.licenses=MIT 237 | dockerfile: Dockerfile 238 | use: buildx 239 | - image_templates: 240 | - "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7{{ end }}" 241 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 242 | goarch: arm 243 | goarm: "7" 244 | build_flag_templates: 245 | - --platform=linux/arm/v7 246 | - --label=org.opencontainers.image.title={{ .ProjectName }} 247 | - --label=org.opencontainers.image.description={{ .ProjectName }} 248 | - --label=org.opencontainers.image.source={{ .GitURL }} 249 | - --label=org.opencontainers.image.version=v{{ .Version }} 250 | - --label=org.opencontainers.image.created={{ .Date }} 251 | - --label=org.opencontainers.image.revision={{ .FullCommit }} 252 | - --label=org.opencontainers.image.licenses=MIT 253 | dockerfile: Dockerfile 254 | use: buildx 255 | 256 | docker_manifests: 257 | - name_template: "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:latest{{ end }}" 258 | image_templates: 259 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 260 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 261 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 262 | - name_template: "{{ if not .IsNightly }}ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:latest{{ end }}" 263 | image_templates: 264 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 265 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 266 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 267 | - name_template: "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Major }}.{{ .Minor }}{{ end }}" 268 | image_templates: 269 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 270 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 271 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 272 | - name_template: "{{ if not .IsNightly }}ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Major }}.{{ .Minor }}{{ end }}" 273 | image_templates: 274 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 275 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 276 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 277 | - name_template: "{{ if not .IsNightly }}docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}{{ end }}" 278 | image_templates: 279 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 280 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 281 | - "docker.io/{{ .Var.docker_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 282 | - name_template: "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}" 283 | image_templates: 284 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-amd64" 285 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-arm64" 286 | - "ghcr.io/{{ .Var.ghcr_io_registry_owner }}/{{ .ProjectName }}:v{{ .Version }}-armv7" 287 | 288 | docker_signs: 289 | - cmd: cosign 290 | artifacts: manifests 291 | output: true 292 | args: 293 | - "sign" 294 | - "${artifact}" 295 | - "--yes" 296 | 297 | git: 298 | tag_sort: semver 299 | 300 | release: 301 | prerelease: auto 302 | footer: 303 | from_url: 304 | url: https://raw.githubusercontent.com/charmbracelet/meta/main/footer.md 305 | -------------------------------------------------------------------------------- /notarize.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json 2 | version: 2 3 | notarize: 4 | macos: 5 | - enabled: '{{ isEnvSet "MACOS_SIGN_P12" }}' 6 | sign: 7 | certificate: "{{.Env.MACOS_SIGN_P12}}" 8 | password: "{{.Env.MACOS_SIGN_PASSWORD}}" 9 | entitlements: '{{ envOrDefault "MACOS_SIGN_ENTITLEMENTS" "" }}' 10 | notarize: 11 | issuer_id: "{{.Env.MACOS_NOTARY_ISSUER_ID}}" 12 | key_id: "{{.Env.MACOS_NOTARY_KEY_ID}}" 13 | key: "{{.Env.MACOS_NOTARY_KEY}}" 14 | -------------------------------------------------------------------------------- /scripts/run-lint-sync.sh: -------------------------------------------------------------------------------- 1 | # NOTE(@andreynering): This script runs the `lint-sync.yml` workflow for 2 | # all public repositories. 3 | 4 | REPOS=$(gh repo list charmbracelet --visibility public --no-archived --limit 1000 --json "name" -t '{{range .}}{{printf "%s\n" .name}}{{end}}') 5 | REPOS=$(echo "$REPOS" | awk '$0 != "x" && $0 != ".github" && $0 != "meta" && $0 != "homebrew-tap" && $0 != "scoop-bucket"' | sort) 6 | 7 | for repo in $REPOS; do 8 | echo "Dispatching lint-sync.yml for $repo" 9 | gh workflow run -R charmbracelet/$repo lint-sync.yml 10 | done 11 | -------------------------------------------------------------------------------- /templates/README.md: -------------------------------------------------------------------------------- 1 | # Project Name 2 | 3 |

4 | Project logo
5 | Latest Release 6 | GoDoc 7 | Build Status 8 | 9 |

10 | 11 | About the tool 12 | 13 | -> insert screen shot 14 | 15 | 16 | ## Features 17 | 18 | ## Installation 19 | 20 | ### Package Manager 21 | 22 | ... is a single binary called `...`. You can get it from a package 23 | manager: 24 | 25 | ```bash 26 | # macOS or Linux 27 | brew tap charmbracelet/tap && brew install charmbracelet/tap/ 28 | 29 | # Arch Linux 30 | pacman -S 31 | 32 | # Windows (with Scoop) 33 | scoop install 34 | chocolatey install 35 | ``` 36 | 37 | You can also download a binary from the [releases][releases] page. Packages are 38 | available in Alpine, Debian, and RPM formats. Binaries are available for Linux, 39 | macOS, and Windows. 40 | 41 | [releases]: https://github.com/charmbracelet//releases 42 | 43 | ### Go 44 | 45 | Or just install it with `go`: 46 | 47 | ```bash 48 | go install github.com/charmbracelet/@latest 49 | ``` 50 | 51 | ## Build From Source 52 | 53 | Or just build it yourself (requires Go 1.1x+): 54 | 55 | ```bash 56 | git clone https://github.com/charmbracelet/.git 57 | cd 58 | go build [./cmd/product] 59 | ``` 60 | 61 | ## Set up 62 | 63 | ## Additional Configuration 64 | 65 | ## Feedback 66 | 67 | We’d love to hear your thoughts on this project. Feel free to drop us a note! 68 | 69 | - [Twitter](https://twitter.com/charmcli) 70 | - [The Fediverse](https://mastodon.social/@charmcli) 71 | - [Discord](https://charm.sh/chat) 72 | 73 | ## License 74 | 75 | [MIT](https://github.com/charmbracelet/meta/raw/main/LICENSE) 76 | 77 | --- 78 | 79 | Part of [Charm](https://charm.sh). 80 | 81 | The Charm logo 82 | 83 | 84 | Charm热爱开源 • Charm loves open source 85 | --------------------------------------------------------------------------------