Skip to content

feat: add initial support for source RPMs#3412

Open
twpayne wants to merge 2 commits intogoreleaser:mainfrom
twpayne:srpm
Open

feat: add initial support for source RPMs#3412
twpayne wants to merge 2 commits intogoreleaser:mainfrom
twpayne:srpm

Conversation

@twpayne
Copy link
Contributor

@twpayne twpayne commented Sep 28, 2022

This PR adds support for generating source RPMs, fixing #3136.

Firstly, thank you for the excellent architecture in goreleaser! It was much easier to add this initial functionality than I expected.

This PR is not ready for merge yet, but is in reasonable shape, and ready for expert input:

  • It generates reasonable .src.rpm files that seem to have the correct contents.
  • the .spec file is configurable.
  • it seems to integrate well with goreleaser's architecture.

There are a certainly missing features:

  • more thorough tests
  • documentation

There are a number of unanswered questions:

  • does this integrate with goreleaser correctly?
  • right now, this PR uses google/rpmpack directly instead of goreleaser/nfpm; should it use goreleaser/nfpm instead?
  • what, exactly should the spec file template look like? I tried to follow Fedora's guidelines on .spec files for Go projects but still have many questions, especially as we're distributing source RPMs that build final binaries and don't want to create packages for every single dependency.

All feedback very welcome!

closes #3136

@pull-request-size pull-request-size bot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Sep 28, 2022
@twpayne
Copy link
Contributor Author

twpayne commented Sep 28, 2022

The CI failure looks like grype had some kind of internal failure unrelated to this PR. This PR does not change the project's dependencies apart from promoting an indirect dependency on github.com/google/rpmpack to a direct dependency.

@codecov
Copy link

codecov bot commented Sep 28, 2022

Codecov Report

❌ Patch coverage is 77.20207% with 44 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.55%. Comparing base (69ce847) to head (3e99dc0).
⚠️ Report is 6 commits behind head on main.

Files with missing lines Patch % Lines
internal/pipe/srpm/srpm.go 76.71% 29 Missing and 15 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3412      +/-   ##
==========================================
- Coverage   82.61%   82.55%   -0.07%     
==========================================
  Files         165      166       +1     
  Lines       16594    16787     +193     
==========================================
+ Hits        13709    13858     +149     
- Misses       2290     2319      +29     
- Partials      595      610      +15     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@caarlos0
Copy link
Member

The CI failure looks like grype had some kind of internal failure unrelated to this PR. This PR does not change the project's dependencies apart from promoting an indirect dependency on github.com/google/rpmpack to a direct dependency.

yes, it checks for vulns... and turns out that go's base image has as couple of them 👀

@caarlos0
Copy link
Member

caarlos0 commented Sep 28, 2022

I think we should be able to use nfpm itself to create the source rpms, as, afaik (and pls correct me if I'm wrong), are regular rpms with some different files in different places and (maybe) extra metadata?

if there are options missing for that on nfpm, we can certainly add those there.

the rpmpack thingy also can become an issue as we are using an internal fork of it in newer versions of nfpm cc/ @goreleaser/nfpm

@caarlos0
Copy link
Member

oh, and most importantly, thanks for the PR! 💜

@twpayne twpayne force-pushed the srpm branch 2 times, most recently from bb24db1 to 8929b89 Compare September 28, 2022 16:48
@twpayne
Copy link
Contributor Author

twpayne commented Sep 28, 2022

Thanks for the feedback! I've updated the PR to use goreleaser/nfpm/v2. I'm reasonably sure that all the required functionality is already present.

I still need to find out exactly what the spec file should look like, so spec.tmpl is still a work in progress.

@caarlos0
Copy link
Member

caarlos0 commented Sep 28, 2022

awesome @twpayne! I don't know how srpms spec files work either, but I'll study about them when I can

@twpayne
Copy link
Contributor Author

twpayne commented Sep 28, 2022

I think the tricky bits with the .spec file will be:

  • The guidelines for .spec files vary from distribution to distribution. I've started by following the Fedora guidelines, but there's a lot of variation.
  • It contains commands to build the project from source, which means in theory reproducing logic from the builds: section of GoReleaser's config.
  • Some distributions (including Fedora) prefer that every single dependency (i.e. each line in go.mod) to be its own package and for the final package to depend on all of these. I think it's OK to ignore this for now.
  • As an eventual inconsistency, the RPMs built by goreleaser will not be the same as the RPMs built from source RPMs built be goreleaser, but I also think this is OK.

The current approach in this PR is to provide a basic default template that should be OK for simple projects, but leave the option for the user to specify their own .spec file template if needed. I suspect that we'll need to add the option to read the .spec file template from a file (as opposed to having it inline in .goreleaser.yaml) as the template will be quite large.

For the record, I won't have much time to work on this for the next ten days or so, but am keen to get good source RPM support added to goreleaser :)

@caarlos0
Copy link
Member

caarlos0 commented Sep 29, 2022

but leave the option for the user to specify their own .spec file template if needed

yes, I think this is the important bit... so users that need more/different stuff can write their spec files themselves, and still use templates for things like version, hashes, etc..

I suspect that we'll need to add the option to read the .spec file template from a file (as opposed to having it inline in .goreleaser.yaml) as the template will be quite large.

yes, probably a good idea as well

For the record, I won't have much time to work on this for the next ten days or so, but am keen to get good source RPM support added to goreleaser :)

same here! will be more offline for a couple of days next week, so if I take too long to reply its probably because of that! Any way, I'm excited to get this into goreleaser as well, if posssible on v1.12.0 or v1.13.0 (next minors) 🤘 (EDIT: no pressure whatsoever, if it is not ready by then its totally fine, and of course I'll help whenever I can 🙏)

@caarlos0 caarlos0 self-requested a review October 5, 2022 02:06
@caarlos0 caarlos0 added the enhancement New feature or request label Oct 5, 2022
@caarlos0
Copy link
Member

hey! anything I could help with here?

@twpayne
Copy link
Contributor Author

twpayne commented Jun 14, 2023

Sorry, I haven't looked at this in a while. I think the code is correct, but it needs testing. I won't have time to look at this again for several weeks, so feel free to close this if the feature is not needed.

@caarlos0
Copy link
Member

hey, no problem, I'll see if I find some time, or worst case, we look at it together in a couple of weeks

thanks for the heads up and the PR 💜

@frzifus
Copy link

frzifus commented Jan 17, 2024

Hi @twpayne @caarlos0, looks like a great PR so far, thanks! Is there something I can do to support you?

@twpayne
Copy link
Contributor Author

twpayne commented Jan 17, 2024

I've not looked at this for a while. I've just re-pushed to resolve conflicts.

@frzifus if you'd like to help, there are a few areas:

  • Testing. Firstly, does the .src.rpm file generated by this pipe actually work? What changes are needed to the .spec template?
  • Is the pipeline written correctly? The PR was opened over a year ago, and goreleaser's core architecture has evolved since (e.g. how skips are handled). Are there other changes needed?
  • internal/pipe/srpm/srpm.go has a few FIXME/TODO comments, mainly missing fields in structures. It would be great if you could have a look at these.

@frzifus
Copy link

frzifus commented Jan 17, 2024

Thanks, I will come back to you asap. I will try to generate a spec/srpm using go2rpm first. Then Ive something to compare.


// Run the pipe.
func (Pipe) Run(ctx *context.Context) error {
sourceArchives := ctx.Artifacts.Filter(artifact.ByType(artifact.UploadableSourceArchive)).List()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems the result for me here is always nil. But I expect my test config might be wrong?

May I ask, do you have a config that you used for testing? :)

Here is what I used so far
---
version: 1

env:
  - GO111MODULE=on

before:
  hooks:
    - go mod tidy

gomod:
  proxy: true

report_sizes: true

git:
  ignore_tags:
    - "{{ if not .IsNightly }}nightly{{ end }}"

metadata:
  mod_timestamp: "{{ .CommitTimestamp }}"

builds:
  - env:
      - CGO_ENABLED=0
    goos:
      - linux
    goarch:
      - amd64
    mod_timestamp: "{{ .CommitTimestamp }}"
    main: ./cmd/vlookup/main.go
    flags:
      - -trimpath
    ldflags:
      - -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{ .CommitDate }} -X main.builtBy=goreleaser -X main.treeState={{ .IsGitDirty }}

universal_binaries:
  - replace: false

checksum:
  name_template: "checksums.txt"

srpm:

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've not run the code in this PR for a long time. I think you need to build a source archive, something like:

source:
  enabled: true
  prefix_template: '{{ .ProjectName }}-{{ .Version }}/'

@twpayne
Copy link
Contributor Author

twpayne commented Aug 12, 2024

For info, I have some time to work on this again, but am currently blocked by #5069.

@twpayne twpayne force-pushed the srpm branch 2 times, most recently from 1838b53 to db87749 Compare August 31, 2024 14:54
@twpayne
Copy link
Contributor Author

twpayne commented Jan 3, 2025

Tried again to work on this and hit #5409 🙈

@caarlos0
Copy link
Member

@twpayne sorry for the delay, I'll review this sometime in the next couple of weeks

having a couple of crazy days here as well hehe

Copy link
Member

@caarlos0 caarlos0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking good!

Comment on lines +65 to +66
// FIXME check source RPM contents using https://github.com/sassoftware/go-rpmutils?
// FIXME check source RPM contents using https://github.com/cavaliergopher/rpm?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might be worth it yes

@caarlos0
Copy link
Member

caarlos0 commented Jun 7, 2025

@twpayne what do you think about this: goreleaser/nfpm#935

@twpayne
Copy link
Contributor Author

twpayne commented Jun 7, 2025

Looks good to me :)

@caarlos0
Copy link
Member

caarlos0 commented Jun 7, 2025

Nice! Merged & released: https://github.com/goreleaser/nfpm/releases/tag/v2.43.0

@twpayne twpayne force-pushed the srpm branch 4 times, most recently from 3f40f19 to 33775b6 Compare July 7, 2025 13:10
@twpayne twpayne marked this pull request as ready for review August 11, 2025 23:47
@twpayne
Copy link
Contributor Author

twpayne commented Aug 11, 2025

This PR is now ready for review/merging.

I think it's OK to release this as an alpha feature for advanced users. It's far from easy-to-use, but we have to start somewhere :)

  • Currently, you still have to write your own .spec file template, but given the complexity of .spec files, this seems unavoidable. Maybe in the future it will be possible to provide a default .spec file template that covers simple Go projects.
  • The documentation is minimal and needs to be improved. For people who understand .spec files and Go templates, the documentation is currently minimal but sufficient. Others are likely to get lost very quickly.
  • I don't think any more code changes to goreleaser or nfpm are required after this PR is merged. The only remaining changes are a default .spec file template and better documentation.
  • The CI failures seem unrelated to this PR.

This is probably setting a record for the longest-ever open PR (2.5 years now!) but I do want to help get this functionality into goreleaser :)

Copy link
Member

@caarlos0 caarlos0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! This is looking really good!

Should we document all the options available? (I can do it btw if you don't want or can't rn).

Also would be nice to have, in the docs, a minimal starter spec template, maybe? wdyt?

Finally, this is not uploading these files anywhere... should we put them in the release? I think things like fury.io and cloudsmith? 🤔

@twpayne
Copy link
Contributor Author

twpayne commented Aug 19, 2025

Thanks for the review!

Should we document all the options available? (I can do it btw if you don't want or can't rn).

We can, but this currently requires expertise in the .spec format to use. The changes to .goreleaser.yml and the .spec template I'm using for testing with chezmoi is in twpayne/chezmoi@225e5b5.

This .spec template is based on one written by @mikelolasagasti in https://bugzilla.redhat.com/show_bug.cgi?id=2386221.

There are some changes around the source tarball names. As I understand it, goreleaser uses .Versions like 2.64.0-SNAPSHOT-225e5b598 for snapshot builds, which rpm does not understand, so I have to use goreleaser's .RawVersion instead in some places.

To reproduce my current state:

  1. Build goreleaser with this PR.

  2. Checkout https://github.com/twpayne/chezmoi and switch to the srpm branch.

  3. Build the srpm with goreleaser:

    goreleaser release --clean --skip=chocolatey,sign,nfpm,snapcraft,winget,scoop --snapshot
    
  4. Copy the dist/chezmoi-2.64.0-SNAPSHOT-225e5b598.src.rpm to a RPM-based distro (I'm using Fedora).

  5. Install the srpm with

    rpm -i chezmoi-2.64.0-SNAPSHOT-225e5b598.src.rpm
    
  6. Build the srpm with

    rpmbuild --rebuild chezmoi-2.64.0-SNAPSHOT-225e5b598.src.rpm
    

On my setup, this currently fails with:

cd /home/twp/rpmbuild/BUILD/chezmoi-2.64.0-build/chezmoi-2.64.0/_build/pkg/mod/cache/vcs/ff8d3c48c38851ad2627d3f838dbec82c248632a3ab4442eac08925a273addab; git ls-remote -q origin
verifying github.com/charmbracelet/x/[email protected]: checksum mismatch
        downloaded: h1:LT77A3bpevRD0yZ5NDR5nonS7N83mxzzGwuZcTGezLE=
        go.sum:     h1:rL3Koar5XvX0pHGfovN03f5cxLbCF2YvLeyz7D2jVDQ=

SECURITY ERROR
This download does NOT match an earlier download recorded in go.sum.
The bits may have been replaced on the origin server, or an attacker may
have intercepted the download attempt.

For more information, see 'go help module-auth'.
error: Bad exit status from /var/tmp/rpm-tmp.p7bb8p (%build)

...which seems related to how Fedora builds Go packages (note tens of other modules build just fine, github.com/charmbracelet/x/[email protected] is the first one to fail).

Also would be nice to have, in the docs, a minimal starter spec template, maybe? wdyt?

All of the above is a long way to say I don't have a working minimal starter spec template yet, but I don't think there are any more changes required to the goreleaser code.

@coderabbitai

This comment was marked as off-topic.

coderabbitai[bot]

This comment was marked as off-topic.

@twpayne
Copy link
Contributor Author

twpayne commented Dec 5, 2025

Sorry, I'm not going to trawl through pages of LLM review slop to determine what is valid and what is BS.

Feel free to close this PR.

@caarlos0
Copy link
Member

@twpayne yeah i was trying this thing out but didn't really like it too much - its way too verbose. Will disable it - sorry for the noise.

@caarlos0
Copy link
Member

@twpayne besides docs, anything else you think is missing here?

Let me know, maybe i can finish it so we can release this 🙏

@caarlos0 caarlos0 mentioned this pull request Jan 30, 2026
12 tasks
@twpayne
Copy link
Contributor Author

twpayne commented Jan 30, 2026

I think it's ready to be released as an experimental component. It probably needs more documentation, and there's so much variation in SRPMs that I don't think it's realistic to provide a default SRPM template.

@caarlos0 caarlos0 added this to the v2.15.0 milestone Mar 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Generate source RPMs

4 participants