diff --git a/.github/config/goreleaser.yaml b/.github/config/goreleaser.yaml index 60696bf9f3..351813dd65 100644 --- a/.github/config/goreleaser.yaml +++ b/.github/config/goreleaser.yaml @@ -90,18 +90,6 @@ changelog: - '^docs:' - '^test:' -brews: - - name: ocm - repository: - owner: open-component-model - name: homebrew-tap - token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" - directory: Formula - homepage: "https://ocm.software/" - description: "The OCM CLI makes it easy to create component versions and embed them in build processes." - test: | - system "#{bin}/ocm --version" - nfpms: - id: debian package_name: ocm-cli diff --git a/.github/workflows/publish-to-other-than-github.yaml b/.github/workflows/publish-to-other-than-github.yaml index 4e3d951398..2d5c0d46a9 100644 --- a/.github/workflows/publish-to-other-than-github.yaml +++ b/.github/workflows/publish-to-other-than-github.yaml @@ -19,6 +19,60 @@ on: types: [ocm-cli-release] jobs: + push-to-brew-tap: + name: Update Homebrew Tap + runs-on: macos-latest + env: + REPO: open-component-model/homebrew-tap + steps: + - name: Ensure proper version + run: | + if [ -n "${{ github.event.inputs.version }}" ]; then + echo "RELEASE_VERSION=$(echo ${{ github.event.inputs.version }} | tr -d ['v'])" >> $GITHUB_ENV + exit 0 + fi + if [ -n "${{ github.event.client_payload.version }}" ]; then + echo "RELEASE_VERSION=$(echo ${{ github.event.client_payload.version }} | tr -d ['v'])" >> $GITHUB_ENV + exit 0 + fi + echo "Version not provided" + exit 1 + - name: Generate token + id: generate_token + uses: tibdex/github-app-token@v2 + with: + app_id: ${{ secrets.OCMBOT_APP_ID }} + private_key: ${{ secrets.OCMBOT_PRIV_KEY }} + - name: Get Update Script + uses: actions/checkout@v4 + with: + path: scripts + sparse-checkout: 'hack/brew' + - name: Checkout + uses: actions/checkout@v4 + with: + repository: ${{ env.REPO }} + token: ${{ steps.generate_token.outputs.token }} + - name: Update Homebrew Tap + run: | + formula=$(go run scripts/hack/brew \ + --version ${{ env.RELEASE_VERSION }} \ + --template scripts/hack/brew/ocm_formula_template.rb.tpl \ + --outputDirectory Formula) + mkdir -p Aliases + ln -s Formula/$(basename formula) Aliases/ocm + rm -r scripts + - name: Create Pull Request + uses: peter-evans/create-pull-request@v7 + with: + token: ${{ steps.generate_token.outputs.token }} + title: "chore: update OCM CLI to v${{ env.RELEASE_VERSION }}" + commit-message: "[github-actions] update OCM CLI to v${{ env.RELEASE_VERSION }}" + branch: chore/update-ocm-cli/${{ env.RELEASE_VERSION }} + delete-branch: true + sign-commits: true + body: | + Update OCM CLI vendor hash (see: .github/workflows/flake_vendorhash.yaml) push-to-aur: name: Update Arch Linux User Repository diff --git a/hack/brew/main.go b/hack/brew/main.go new file mode 100644 index 0000000000..61ed3a0bdb --- /dev/null +++ b/hack/brew/main.go @@ -0,0 +1,95 @@ +package main + +import ( + "flag" + "fmt" + "io" + "log" + "net/http" + "os" + "path/filepath" + "strings" + "text/template" +) + +const ReleaseURL = "https://github.com/open-component-model/ocm/releases/download" + +const ClassName = "Ocm" + +func main() { + version := flag.String("version", "", "version of the OCM formula") + templateFile := flag.String("template", "ocm_formula_template.rb.tpl", "path to the template file") + outputDir := flag.String("outputDirectory", ".", "path to the output directory") + + flag.Parse() + + if *version == "" { + log.Fatalf("version is required") + } + + architectures := []string{"amd64", "arm64"} + oses := []string{"darwin", "linux"} + values := map[string]string{ + "Version": *version, + } + + for _, targetOs := range oses { + for _, arch := range architectures { + url := fmt.Sprintf( + "%s/v%[2]s/ocm-%[2]s-%s-%s.tar.gz.sha256", ReleaseURL, *version, targetOs, arch) + rawDigest, err := http.Get(url) + if err != nil { + log.Fatalf("failed to get digest for %s/%s: %v", targetOs, arch, err) + } + digestBytes, err := io.ReadAll(rawDigest.Body) + if err != nil { + log.Fatalf("failed to read digest for %s/%s: %v", targetOs, arch, err) + } + if err := rawDigest.Body.Close(); err != nil { + log.Fatalf("failed to close response body for %s/%s: %v", targetOs, arch, err) + } + digest := strings.TrimSpace(string(digestBytes)) + + values[fmt.Sprintf("%s_%s_sha256", targetOs, arch)] = digest + } + } + + // Parse and execute the template + tmpl, err := template.New(filepath.Base(*templateFile)).Funcs(template.FuncMap{ + "classname": func() string { + return fmt.Sprintf("%sAT%s", ClassName, strings.ReplaceAll(*version, ".", "")) + }, + }).ParseFiles(*templateFile) + if err != nil { + log.Fatalf("failed to parse template: %v", err) + } + + outputFile := fmt.Sprintf("ocm@%s.rb", *version) + + fi, err := os.Stat(*outputDir) + if os.IsNotExist(err) { + if err := os.MkdirAll(*outputDir, 0755); err != nil { + log.Fatalf("failed to create output directory: %v", err) + } + } else if err != nil { + log.Fatalf("failed to stat output directory: %v", err) + } else if !fi.IsDir() { + log.Fatalf("output directory is not a directory") + } + + versionedFormula, err := os.Create(fmt.Sprintf(filepath.Join(*outputDir, outputFile))) + if err != nil { + log.Fatalf("failed to parse template: %v", err) + } + defer func() { + if err := versionedFormula.Close(); err != nil { + log.Fatalf("failed to close file: %v", err) + } + }() + + if err := tmpl.Execute(versionedFormula, values); err != nil { + log.Fatalf("failed to execute template: %v", err) + } + + println(versionedFormula.Name()) +} diff --git a/hack/brew/ocm_formula_template.rb.tpl b/hack/brew/ocm_formula_template.rb.tpl new file mode 100644 index 0000000000..60a7f9013c --- /dev/null +++ b/hack/brew/ocm_formula_template.rb.tpl @@ -0,0 +1,55 @@ +{{- /* Go template for Homebrew Formula */ -}} +# typed: false +# frozen_string_literal: true + +class {{ classname }} < Formula + desc "The OCM CLI makes it easy to create component versions and embed them in build processes." + homepage "https://ocm.software/" + version "{{ .Version }}" + + on_macos do + on_intel do + url "{{ .ReleaseURL }}/v{{ .Version }}/ocm-{{ .Version }}-darwin-amd64.tar.gz" + sha256 "{{ .darwin_amd64_sha256 }}" + + def install + bin.install "ocm" + end + end + on_arm do + url "{{ .ReleaseURL }}/v{{ .Version }}/ocm-{{ .Version }}-darwin-arm64.tar.gz" + sha256 "{{ .darwin_arm64_sha256 }}" + + def install + bin.install "ocm" + end + end + end + + on_linux do + on_intel do + if Hardware::CPU.is_64_bit? + url "{{ .ReleaseURL }}/v{{ .Version }}/ocm-{{ .Version }}-linux-amd64.tar.gz" + sha256 "{{ .linux_amd64_sha256 }}" + + def install + bin.install "ocm" + end + end + end + on_arm do + if Hardware::CPU.is_64_bit? + url "{{ .ReleaseURL }}/v{{ .Version }}/ocm-{{ .Version }}-linux-arm64.tar.gz" + sha256 "{{ .linux_arm64_sha256 }}" + + def install + bin.install "ocm" + end + end + end + end + + test do + system "#{bin}/ocm --version" + end +end