Skip to content

Commit

Permalink
feat: add packager-specific nfpm config (#1849)
Browse files Browse the repository at this point in the history
* feat: Add deb packager-specific nfpm config (#1829)

* Use env vars containing nfpm ids for deb pgp passphrase

* Add docs for nfpm id in env var

* Custon -> Custom

* Switch test cases

* Forward RPM specific config to nfpm

* Document rpm-specific nfpm config

* Add APK-specific nfpm config

* Document apk-specific nfpm config

* avaiable -> available

* Add deb scripts templates to nfpm config
  • Loading branch information
jonathanlloyd committed Nov 5, 2020
1 parent f1049b9 commit 17e5674
Show file tree
Hide file tree
Showing 6 changed files with 446 additions and 0 deletions.
57 changes: 57 additions & 0 deletions internal/pipe/nfpm/nfpm.go
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"os"
"path/filepath"
"strings"

"github.com/apex/log"
"github.com/goreleaser/nfpm"
Expand Down Expand Up @@ -173,6 +174,43 @@ func create(ctx *context.Context, fpm config.NFPM, format, arch string, binaries
PreRemove: overridden.Scripts.PreRemove,
PostRemove: overridden.Scripts.PostRemove,
},
Deb: nfpm.Deb{
Scripts: nfpm.DebScripts{
Rules: overridden.Deb.Scripts.Rules,
Templates: overridden.Deb.Scripts.Templates,
},
Triggers: nfpm.DebTriggers{
Interest: overridden.Deb.Triggers.Interest,
InterestAwait: overridden.Deb.Triggers.InterestAwait,
InterestNoAwait: overridden.Deb.Triggers.InterestNoAwait,
Activate: overridden.Deb.Triggers.Activate,
ActivateAwait: overridden.Deb.Triggers.ActivateAwait,
ActivateNoAwait: overridden.Deb.Triggers.ActivateNoAwait,
},
Breaks: overridden.Deb.Breaks,
VersionMetadata: overridden.Deb.VersionMetadata,
Signature: nfpm.DebSignature{
KeyFile: overridden.Deb.Signature.KeyFile,
KeyPassphrase: getPassphraseFromEnv(ctx, "DEB", fpm.ID),
Type: overridden.Deb.Signature.Type,
},
},
RPM: nfpm.RPM{
Group: overridden.RPM.Group,
Compression: overridden.RPM.Compression,
ConfigNoReplaceFiles: overridden.RPM.ConfigNoReplaceFiles,
Signature: nfpm.RPMSignature{
KeyFile: overridden.RPM.Signature.KeyFile,
KeyPassphrase: getPassphraseFromEnv(ctx, "RPM", fpm.ID),
},
},
APK: nfpm.APK{
Signature: nfpm.APKSignature{
KeyFile: overridden.APK.Signature.KeyFile,
KeyPassphrase: getPassphraseFromEnv(ctx, "APK", fpm.ID),
KeyName: overridden.APK.Signature.KeyName,
},
},
},
}

Expand Down Expand Up @@ -214,3 +252,22 @@ func create(ctx *context.Context, fpm config.NFPM, format, arch string, binaries
})
return nil
}

func getPassphraseFromEnv(ctx *context.Context, packager string, nfpmID string) string {
var passphrase string

nfpmID = strings.ToUpper(nfpmID)
packagerSpecificPassphrase := ctx.Env[fmt.Sprintf(
"NFPM_%s_%s_PASSPHRASE",
nfpmID,
packager,
)]
if packagerSpecificPassphrase != "" {
passphrase = packagerSpecificPassphrase
} else {
generalPassphrase := ctx.Env[fmt.Sprintf("NFPM_%s_PASSPHRASE", nfpmID)]
passphrase = generalPassphrase
}

return passphrase
}
214 changes: 214 additions & 0 deletions internal/pipe/nfpm/nfpm_test.go
Expand Up @@ -347,6 +347,220 @@ func TestOverrides(t *testing.T) {
require.Equal(t, "bar", merged.FileNameTemplate)
}

func TestDebSpecificConfig(t *testing.T) {
folder, err := ioutil.TempDir("", "archivetest")
require.NoError(t, err)
var dist = filepath.Join(folder, "dist")
require.NoError(t, os.Mkdir(dist, 0755))
require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0755))
var binPath = filepath.Join(dist, "mybin", "mybin")
_, err = os.Create(binPath)
require.NoError(t, err)
var ctx = context.New(config.Project{
ProjectName: "mybin",
Dist: dist,
NFPMs: []config.NFPM{
{
ID: "someid",
Builds: []string{"default"},
Formats: []string{"deb"},
NFPMOverridables: config.NFPMOverridables{
PackageName: "foo",
Files: map[string]string{
"./testdata/testfile.txt": "/usr/share/testfile.txt",
},
Deb: config.NFPMDeb{
Signature: config.NFPMDebSignature{
KeyFile: "./testdata/privkey.gpg",
},
},
},
},
},
})
ctx.Version = "1.0.0"
ctx.Git = context.GitInfo{CurrentTag: "v1.0.0"}
for _, goos := range []string{"linux", "darwin"} {
for _, goarch := range []string{"amd64", "386"} {
ctx.Artifacts.Add(&artifact.Artifact{
Name: "mybin",
Path: binPath,
Goarch: goarch,
Goos: goos,
Type: artifact.Binary,
Extra: map[string]interface{}{
"ID": "default",
},
})
}
}

t.Run("no passphrase set", func(t *testing.T) {
require.Contains(
t,
Pipe{}.Run(ctx).Error(),
`key is encrypted but no passphrase was provided`,
)
})

t.Run("general passphrase set", func(t *testing.T) {
ctx.Env = map[string]string{
"NFPM_SOMEID_PASSPHRASE": "hunter2",
}
require.NoError(t, Pipe{}.Run(ctx))
})

t.Run("packager specific passphrase set", func(t *testing.T) {
ctx.Env = map[string]string{
"NFPM_SOMEID_DEB_PASSPHRASE": "hunter2",
}
require.NoError(t, Pipe{}.Run(ctx))
})
}

func TestRPMSpecificConfig(t *testing.T) {
folder, err := ioutil.TempDir("", "archivetest")
require.NoError(t, err)
var dist = filepath.Join(folder, "dist")
require.NoError(t, os.Mkdir(dist, 0755))
require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0755))
var binPath = filepath.Join(dist, "mybin", "mybin")
_, err = os.Create(binPath)
require.NoError(t, err)
var ctx = context.New(config.Project{
ProjectName: "mybin",
Dist: dist,
NFPMs: []config.NFPM{
{
ID: "someid",
Builds: []string{"default"},
Formats: []string{"rpm"},
NFPMOverridables: config.NFPMOverridables{
PackageName: "foo",
Files: map[string]string{
"./testdata/testfile.txt": "/usr/share/testfile.txt",
},
RPM: config.NFPMRPM{
Signature: config.NFPMRPMSignature{
KeyFile: "./testdata/privkey.gpg",
},
},
},
},
},
})
ctx.Version = "1.0.0"
ctx.Git = context.GitInfo{CurrentTag: "v1.0.0"}
for _, goos := range []string{"linux", "darwin"} {
for _, goarch := range []string{"amd64", "386"} {
ctx.Artifacts.Add(&artifact.Artifact{
Name: "mybin",
Path: binPath,
Goarch: goarch,
Goos: goos,
Type: artifact.Binary,
Extra: map[string]interface{}{
"ID": "default",
},
})
}
}

t.Run("no passphrase set", func(t *testing.T) {
require.Contains(
t,
Pipe{}.Run(ctx).Error(),
`key is encrypted but no passphrase was provided`,
)
})

t.Run("general passphrase set", func(t *testing.T) {
ctx.Env = map[string]string{
"NFPM_SOMEID_PASSPHRASE": "hunter2",
}
require.NoError(t, Pipe{}.Run(ctx))
})

t.Run("packager specific passphrase set", func(t *testing.T) {
ctx.Env = map[string]string{
"NFPM_SOMEID_RPM_PASSPHRASE": "hunter2",
}
require.NoError(t, Pipe{}.Run(ctx))
})
}

func TestAPKSpecificConfig(t *testing.T) {
folder, err := ioutil.TempDir("", "archivetest")
require.NoError(t, err)
var dist = filepath.Join(folder, "dist")
require.NoError(t, os.Mkdir(dist, 0755))
require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0755))
var binPath = filepath.Join(dist, "mybin", "mybin")
_, err = os.Create(binPath)
require.NoError(t, err)
var ctx = context.New(config.Project{
ProjectName: "mybin",
Dist: dist,
NFPMs: []config.NFPM{
{
ID: "someid",
Maintainer: "me@me",
Builds: []string{"default"},
Formats: []string{"apk"},
NFPMOverridables: config.NFPMOverridables{
PackageName: "foo",
Files: map[string]string{
"./testdata/testfile.txt": "/usr/share/testfile.txt",
},
APK: config.NFPMAPK{
Signature: config.NFPMAPKSignature{
KeyFile: "./testdata/rsa.priv",
},
},
},
},
},
})
ctx.Version = "1.0.0"
ctx.Git = context.GitInfo{CurrentTag: "v1.0.0"}
for _, goos := range []string{"linux", "darwin"} {
for _, goarch := range []string{"amd64", "386"} {
ctx.Artifacts.Add(&artifact.Artifact{
Name: "mybin",
Path: binPath,
Goarch: goarch,
Goos: goos,
Type: artifact.Binary,
Extra: map[string]interface{}{
"ID": "default",
},
})
}
}

t.Run("no passphrase set", func(t *testing.T) {
require.Contains(
t,
Pipe{}.Run(ctx).Error(),
`key is encrypted but no passphrase was provided`,
)
})

t.Run("general passphrase set", func(t *testing.T) {
ctx.Env = map[string]string{
"NFPM_SOMEID_PASSPHRASE": "hunter2",
}
require.NoError(t, Pipe{}.Run(ctx))
})

t.Run("packager specific passphrase set", func(t *testing.T) {
ctx.Env = map[string]string{
"NFPM_SOMEID_APK_PASSPHRASE": "hunter2",
}
require.NoError(t, Pipe{}.Run(ctx))
})
}

func TestSeveralNFPMsWithTheSameID(t *testing.T) {
var ctx = &context.Context{
Config: config.Project{
Expand Down
Binary file added internal/pipe/nfpm/testdata/privkey.gpg
Binary file not shown.
30 changes: 30 additions & 0 deletions internal/pipe/nfpm/testdata/rsa.priv
@@ -0,0 +1,30 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,F681796F2F5F6592720D154E441631AF

U4aCJ0bGTN+/l162THI8CQdVmn62QX7+CxGOrxz8vbPOcMic8ppBD/h4lcUmca1L
B3q9gBV+nM4KWOUjKDsmXJ7PeHrQJxR30RbGKGOP8WZSlf7oqICHX9WfjzsaLmMC
zr7z7osO4DhW0nkr+CJATplKxjF5kry2jsBohmG7AJKVB6JRenpyz/icLrwfeywo
dM1aZEw2Tm6Aso+un+rdmRxvYG5SEVLVh5M334MvOwhKHNGGfNOUJG38uym/sYXM
WbBRyOUhQXabbuHlJdr5V7mnxm+KLi+hZQAIoRsFTS7tkIUpFjtvCS0RI0L6MtkL
3N76xiW82n3SxrPdZdJCGy9AWor66QTmr25yTZpUJMYqpHaXc2pKqZOWZ/U0bAbA
Oyf/CCTwI9lLT1a+CtGTHYTXHHKhQ9n1TI2FI4DRhnDcdDix2S/shF8aeu7mcKF1
SqS8r+DTKzmbohUVa0/Ad9Z6R8Q1Ed+fl2/l0/eb3tI7c7hH+AxV+AqSAgLsZ1/T
SQoIjUX4Kna0U2wLi7wEWlwrQQE2lugoJ2tOH6F33tEd4FFh4CjTw4LKKFEIgjPj
yNKJ5CC+5jQPdyN/utR6Q+PNlxnT5jU02dAupdGfS/On2ecONmBKFCHHT+Sh3F21
Q8zKZPKTUgIqG8JrjIaO1akjJqGgr6c0kefVTYpHEH3HNNkqUvzywIMR7IooPJrD
XQYLMgTuE4ccJk7JN5OCHlSkTHPcrkuD6rRmi7v9zIOMEmwfkN0Ea3HgNJ/7W8gL
mnv47HtwEuuXpyhyQ5xpaJcNWfSaUvSHBr33Ni8rDL2iJu22zEeZXlOU1t4h7wCA
VGd3GBk4n5PILABwILDWKP16bvB3I491QK6m7LehawJNMGDC4Yk379Havcl6BzSX
Rs6NOFcAGyM0VS97HYj3ju7fecdvFwmd86CA92CoK6JbafsQ6o/sOZOhxnrg6nLu
bS26TPwLoqNHrAzg2vTLosbiG3ezge7VuL2GBbQcZm4SsotNLbfpZIhn3JV9/Ivg
rkiUNOEExd52+VImeAJ15Pl6lOb2uAdXwZNsPXfBbanfc5qoggJJlU/xCnQyrPNW
xCi2y3+SQjjlEqdoQbmEEHrU4zzOSj505qDz/Md18W/aih5n1VdzI7Z1YeMAzlpe
X7cGHrQD83AsAtWWv5af5qkHCRYn3fQDGf4svJprsbYxz7e8oAoyjXpKPVbfZcfk
hqlR0T7yN91upFwHhq8q3ZY/CLsZbLecT28M3G7NgE+LtrF0bKcPrDfOCeWyyVBN
wtxPB0P62Nr4jHs5GVO5D1qyCiDMLsS3mwSz3IZn2xf0pit7+O2uu5yIUeGhUN8k
1Y4RwZyGf1e5y7Ulhb5OAbeDYtUTnvgWOqwj5grmACQhhWmKiXX6qUHHn54xyC9P
Yn5f0jdGGVRKINgA+KsipDs3OjMY0D9Dyx3ao646wX+1ypNkUq+hZhykuKlTgqi6
29LdVwXTbcYjc25hbIj9TrXZS7swmwtUhpLwtFyjqrCSMjHW6f6n27Vq8cvL788L
7SbWmpZlxaZA2lj3yjjYnY2bSQBfmA45fF7tBZfHq/ObWFbpvCOU5LMwKjffoPpC
-----END RSA PRIVATE KEY-----

1 comment on commit 17e5674

@vercel
Copy link

@vercel vercel bot commented on 17e5674 Nov 5, 2020

Choose a reason for hiding this comment

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

Please sign in to comment.