Skip to content

Scoop Manifests

After releasing to GitHub, GitLab, or Gitea, GoReleaser can generate and publish a Scoop App Manifest into a repository that you have access to.

The scoop section specifies how the manifest should be created. See the commented example below:

# .goreleaser.yaml
# Since: v1.18
scoops:
  - # Name of the recipe
    #
    # Default: ProjectName
    # Templates: allowed (since v1.19)
    name: myproject

    # URL which is determined by the given Token (github or gitlab)
    #
    # Default:
    #   GitHub: 'https://github.com/<repo_owner>/<repo_name>/releases/download/{{ .Tag }}/{{ .ArtifactName }}'
    #   GitLab: 'https://gitlab.com/<repo_owner>/<repo_name>/-/releases/{{ .Tag }}/downloads/{{ .ArtifactName }}'
    #   Gitea: 'https://gitea.com/<repo_owner>/<repo_name>/releases/download/{{ .Tag }}/{{ .ArtifactName }}'
    # Templates: allowed
    url_template: "http://github.mycompany.com/foo/bar/releases/{{ .Tag }}/{{ .ArtifactName }}"

    # Folder inside the repository to put the scoop.
    #
    # Note that while scoop works if the manifests are in a folder,
    # 'scoop bucket list' will show 0 manifests if they are not in the root
    # folder.
    # In short, it's generally better to leave this empty.
    folder: Scoops

    # Git author used to commit to the repository.
    commit_author:
      name: goreleaserbot
      email: bot@goreleaser.com

    # The project name and current git tag are used in the format string.
    #
    # Templates: allowed
    commit_msg_template: "Scoop update for {{ .ProjectName }} version {{ .Tag }}"

    # Your app's homepage.
    #
    # Templates: allowed (since v1.19)
    homepage: "https://example.com/"

    # Your app's description.
    #
    # Templates: allowed (since v1.19)
    description: "Software to create fast and easy drum rolls."

    # Your app's license
    license: MIT

    # Setting this will prevent goreleaser to actually try to commit the updated
    # manifest leaving the responsibility of publishing it to the user.
    # If set to auto, the release will not be uploaded to the scoop bucket
    # in case there is an indicator for prerelease in the tag e.g. v1.0.0-rc1
    #
    # Templates: allowed (since v1.19)
    skip_upload: true

    # Persist data between application updates
    persist:
      - "data"
      - "config.toml"

    # An array of commands to be executed before an application is installed.
    pre_install: ["Write-Host 'Running preinstall command'"]

    # An array of commands to be executed after an application is installed.
    post_install: ["Write-Host 'Running postinstall command'"]

    # An array of dependencies.
    #
    # Since GoReleaser v1.16
    depends: ["git", "foo"]

    # A two-dimensional array of string, specifies the shortcut values to make available in the startmenu.
    # The array has to contain an executable/label pair. The third and fourth element are optional.
    #
    # Since GoReleaser v1.17.0.
    shortcuts: [["drumroll.exe", "drumroll"]]

    # GOAMD64 to specify which amd64 version to use if there are multiple versions
    # from the build section.
    #
    # Default: 'v1'
    goamd64: v3

    # Repository to push the generated files to.
    repository:
      # Repository owner.
      #
      # Templates: allowed
      owner: caarlos0

      # Repository name.
      #
      # Templates: allowed
      name: my-repo

      # Optionally a branch can be provided.
      #
      # Default: default repository branch
      # Templates: allowed
      branch: main

      # Optionally a token can be provided, if it differs from the token
      # provided to GoReleaser
      # Templates: allowed
      token: "{{ .Env.GITHUB_PERSONAL_AUTH_TOKEN }}"

      # Sets up pull request creation instead of just pushing to the given branch.
      # Make sure the 'branch' property is different from base before enabling
      # it.
      #
      # Since: v1.17
      pull_request:
        # Whether to enable it or not.
        enabled: true

        # Whether to open the PR as a draft or not.
        #
        # Since: v1.19
        draft: true

        # If the pull request template has checkboxes, enabling this will
        # check all of them.
        #
        # Since: v1.20 (pro).
        # This feature is only available in GoReleaser Pro.
        check_boxes: true

        # Base can also be another repository, in which case the owner and name
        # above will be used as HEAD, allowing cross-repository pull requests.
        #
        # Since: v1.19
        base:
          owner: goreleaser
          name: my-repo
          branch: main

      # Clone, create the file, commit and push, to a regular Git repository.
      #
      # Notice that this will only have any effect if the given URL is not
      # empty.
      #
      # Since: v1.18
      git:
        # The Git URL to push.
        #
        # Templates: allowed
        url: 'ssh://git@myserver.com:repo.git'

        # The SSH private key that should be used to commit to the Git
        # repository.
        # This can either be a path or the key contents.
        #
        # IMPORTANT: the key must not be password-protected.
        #
        # WARNING: do not expose your private key in the configuration file!
        #
        # Templates: allowed
        private_key: '{{ .Env.PRIVATE_KEY_PATH }}'

        # The value to be passed to `GIT_SSH_COMMAND`.
        # This is mainly used to specify the SSH private key used to pull/push
        # to the Git URL.
        #
        # Default: 'ssh -i {{ .KeyPath }} -o StrictHostKeyChecking=accept-new -F /dev/null'
        # Templates: allowed
        ssh_command: 'ssh -i {{ .Env.KEY }} -o SomeOption=yes'

Tip

Learn more about the name template engine.

By defining the scoop section, GoReleaser will take care of publishing the Scoop app. Assuming that the project name is drumroll, and the current tag is v1.2.3, the above configuration will generate a drumroll.json manifest in the root of the repository specified in the bucket section.

{
  "version": "1.2.3",
  "architecture": {
    "64bit": {
      "url": "https://github.com/user/drumroll/releases/download/1.2.3/drumroll_1.2.3_windows_amd64.tar.gz",
      "bin": "drumroll.exe",
      "hash": "86920b1f04173ee08773136df31305c0dae2c9927248ac259e02aafd92b6008a"
    },
    "32bit": {
      "url": "https://github.com/user/drumroll/releases/download/1.2.3/drumroll_1.2.3_windows_386.tar.gz",
      "bin": "drumroll.exe",
      "hash": "283faa524ef41987e51c8786c61bb56658a489f63512b32139d222b3ee1d18e6"
    }
  },
  "homepage": "https://example.com/"
}

Your users can then install your app by doing:

scoop bucket add org https://github.com/org/repo.git
scoop install org/drumroll

You can check the Scoop documentation for more details.

Pull Requests

Since v1.17

GoReleaser allows you to, instead of pushing directly to the main branch, push to a feature branch, and open a pull requests with the changes.

Templates

Since v1.19

GoReleaser will check for a .github/PULL_REQUEST_TEMPLATE.md, and set it in the pull request body if it exists.

We do that to prevent extra work for maintainers of things like winget-pkgs, nixpkgs, and so on.

Cross-repository pull requests

Since v1.19

You can also push to a fork, and open the pull request in the original branch.

Here's an example on how to set it up:

# .goreleaser.yml
# ...
something: # can be nix, brews, etc...
  - repository:
      owner: john
      name: repo
      branch: "{{.ProjectName}}-{{.Version}}"
      pull_request:
        enabled: true
        base:
          owner: mike
          name: repo
          branch: main

This will:

  • Create the files into john/repo, in the branch foo-1.2.3 (assuming ProjectName=foo and Version=1.2.3). 1
  • Open a pull request from john/repo into mike/repo, with the branch main as target. 2

Things that don't work

  • GoReleaser will not keep your fork in sync!!! It might or might not be a problem in your case, in which case you'll have to sync it manually.
  • Opening pull requests to a forked repository (go-github does not have the required fields to do it).
  • Since this can fail for a myriad of reasons, if an error happen, it'll log it to the release output, but will not fail the pipeline.

  1. In GitHub's terms, this means head=john:repo:foo-1.2.3 

  2. In GitHub's terms, this means base=mike:repo:main