1
1
Fork 0
mirror of https://github.com/goreleaser/nfpm synced 2024-04-30 12:05:11 +02:00

test: clean up the acceptance tests (#292)

This commit is contained in:
Dj Gilcrease 2021-04-15 13:25:39 -07:00 committed by GitHub
parent 7701bb950c
commit 41077943bd
Signed by: GitHub
GPG Key ID: 4AEE18F83AFDEB23
91 changed files with 878 additions and 1002 deletions

View File

@ -9,14 +9,12 @@ on:
pull_request:
jobs:
goreleaser:
unit-tests:
strategy:
matrix:
go-version: [ ~1.16 ]
go-version: [ 1.16 ]
os: [ ubuntu-latest, macos-latest, windows-latest ]
runs-on: ${{ matrix.os }}
env:
DOCKER_CLI_EXPERIMENTAL: "enabled"
steps:
-
name: Checkout
@ -27,7 +25,51 @@ jobs:
name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.16
go-version: ${{ matrix.go-version }}
-
name: Cache Go modules
uses: actions/cache@v1
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
-
name: Setup
run: make setup
-
name: Make Unit Tests
run: make test
-
name: Diff
run: git diff
-
name: Upload coverage
uses: codecov/codecov-action@v1
if: matrix.os == 'ubuntu-latest'
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage.txt
Acceptance-Tests:
strategy:
matrix:
go-version: [ 1.16 ]
pkgFormats: [ deb, rpm, apk ]
runs-on: ubuntu-latest
env:
DOCKER_CLI_EXPERIMENTAL: "enabled"
NO_TEST_PPC64LE: "true"
steps:
-
name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
-
name: Set up Go
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
-
name: Cache Go modules
uses: actions/cache@v1
@ -39,34 +81,54 @@ jobs:
-
name: Set up QEMU
uses: docker/setup-qemu-action@v1
if: matrix.os == 'ubuntu-latest'
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
if: matrix.os == 'ubuntu-latest'
-
name: Make Setup
run: |
make setup
-
name: Make Acceptance
run: |
TEST_PATTERN=/${{ matrix.pkgFormats }}/ make acceptance
goreleaser:
strategy:
matrix:
go-version: [ 1.16 ]
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
needs:
- unit-tests
- Acceptance-Tests
steps:
-
name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
-
name: Set up Go
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
-
name: Cache Go modules
uses: actions/cache@v1
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
-
name: Setup
run: make setup
-
name: Test
run: make build test
-
name: Acceptance tests
run: make acceptance
if: matrix.os == 'ubuntu-latest'
-
name: Diff
run: git diff
-
name: Upload coverage
uses: codecov/codecov-action@v1
if: matrix.os == 'ubuntu-latest'
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage.txt
name: Make build
run: make build
-
name: Docker Login
if: success() && startsWith(github.ref, 'refs/tags/') && matrix.os == 'ubuntu-latest'
if: success()
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
@ -77,7 +139,7 @@ jobs:
-
name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
if: success() && startsWith(github.ref, 'refs/tags/') && matrix.os == 'ubuntu-latest'
if: success()
with:
version: latest
args: release --rm-dist
@ -85,6 +147,5 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GH_PAT }}
-
name: Clear
if: matrix.os == 'ubuntu-latest'
run: |
rm -f ${HOME}/.docker/config.json
rm -f ${HOME}/.docker/config.json

View File

@ -1,4 +1,4 @@
linters:
enable:
- thelper
- gofumpt
- gofumpt

View File

@ -3,8 +3,8 @@ TEST_PATTERN?=.
TEST_OPTIONS?=
TEST_TIMEOUT?=15m
TEST_PARALLEL?=2
CONTAINER_RUNTIME?=docker
export CONTAINER_RUNTIME
DOCKER_BUILDKIT?=1
export DOCKER_BUILDKIT
export PATH := ./bin:$(PATH)
export GO111MODULE := on
@ -16,11 +16,11 @@ setup:
.PHONY: setup
pull_test_imgs:
grep FROM ./testdata/acceptance/*.dockerfile | cut -f2 -d' ' | sort | uniq | while read -r img; do $(CONTAINER_RUNTIME) pull "$$img"; done
grep -m 1 FROM ./testdata/acceptance/*.dockerfile | cut -f2 -d' ' | sort | uniq | while read -r img; do docker pull "$$img"; done
.PHONY: pull_test_imgs
acceptance: pull_test_imgs
make -e TEST_OPTIONS="-tags=acceptance" test
make -e TEST_PARALLEL="4" -e TEST_OPTIONS="-tags=acceptance" -e TEST_TIMEOUT="60m" -e SOURCE_FILES="acceptance_test.go" test
.PHONY: acceptance
test:
@ -35,7 +35,11 @@ fmt:
gofumpt -w .
.PHONY: fmt
ci: build test acceptance
lint: check
golangci-lint run
.PHONY: check
ci: lint test
.PHONY: ci
build:
@ -57,7 +61,7 @@ imgs:
.PHONY: imgs
serve:
@$(CONTAINER_RUNTIME) run --rm -it -p 8000:8000 -v ${PWD}/www:/docs squidfunk/mkdocs-material
@docker run --rm -it -p 8000:8000 -v ${PWD}/www:/docs squidfunk/mkdocs-material
.PHONY: serve
todo:

View File

@ -18,74 +18,58 @@ import (
)
// nolint: gochecknoglobals
var formats = []string{"deb", "rpm", "apk"}
func TestSimple(t *testing.T) {
for _, format := range formats {
format := format
t.Run(fmt.Sprintf("amd64-%s", format), func(t *testing.T) {
accept(t, acceptParms{
Name: fmt.Sprintf("simple_%s", format),
Conf: "simple.yaml",
Format: format,
Dockerfile: fmt.Sprintf("%s.dockerfile", format),
})
})
t.Run(fmt.Sprintf("i386-%s", format), func(t *testing.T) {
accept(t, acceptParms{
Name: fmt.Sprintf("simple_%s_386", format),
Conf: "simple.386.yaml",
Format: format,
Dockerfile: fmt.Sprintf("%s.386.dockerfile", format),
})
})
t.Run(fmt.Sprintf("ppc64le-%s", format), func(t *testing.T) {
t.Skip("for some reason travis fails to run those")
accept(t, acceptParms{
Name: fmt.Sprintf("simple_%s_ppc64le", format),
Conf: "simple.ppc64le.yaml",
Format: format,
Dockerfile: fmt.Sprintf("%s.ppc64le.dockerfile", format),
})
})
t.Run(fmt.Sprintf("arm64-%s", format), func(t *testing.T) {
accept(t, acceptParms{
Name: fmt.Sprintf("simple_%s_arm64", format),
Conf: "simple.arm64.yaml",
Format: format,
Dockerfile: fmt.Sprintf("%s.arm64.dockerfile", format),
})
})
}
var formatArchs = map[string][]string{
"apk": {"amd64", "arm64", "386", "ppc64le"},
"deb": {"amd64", "arm64", "ppc64le"},
"rpm": {"amd64", "arm64", "ppc64le"},
}
func TestComplex(t *testing.T) {
for _, format := range formats {
format := format
t.Run(fmt.Sprintf("amd64-%s", format), func(t *testing.T) {
accept(t, acceptParms{
Name: fmt.Sprintf("complex_%s", format),
Conf: "complex.yaml",
Format: format,
Dockerfile: fmt.Sprintf("%s.complex.dockerfile", format),
})
})
t.Run(fmt.Sprintf("i386-%s", format), func(t *testing.T) {
accept(t, acceptParms{
Name: fmt.Sprintf("complex_%s_386", format),
Conf: "complex.386.yaml",
Format: format,
Dockerfile: fmt.Sprintf("%s.386.complex.dockerfile", format),
})
})
func TestCore(t *testing.T) {
t.Parallel()
testNames := []string{
"min",
"simple",
"no-glob",
"complex",
"env-var-version",
"overrides",
"meta",
"withchangelog",
"symlink",
"signed",
}
for _, name := range testNames {
for format, architecture := range formatArchs {
for _, arch := range architecture {
func(tt *testing.T, testName, testFormat, testArch string) {
tt.Run(fmt.Sprintf("%s/%s/%s", testFormat, testArch, testName), func(ttt *testing.T) {
ttt.Parallel()
if testArch == "ppc64le" && os.Getenv("NO_TEST_PPC64LE") == "true" {
ttt.Skip("ppc64le arch not supported in pipeline")
}
accept(ttt, acceptParms{
Name: fmt.Sprintf("%s_%s", testName, testArch),
Conf: fmt.Sprintf("core.%s.yaml", testName),
Format: testFormat,
Docker: dockerParams{
File: fmt.Sprintf("%s.dockerfile", testFormat),
Target: testName,
Arch: testArch,
},
})
})
}(t, name, format, arch)
}
}
}
}
func TestConfigNoReplace(t *testing.T) {
t.Parallel()
target := "./testdata/acceptance/tmp/noreplace_old_rpm.rpm"
require.NoError(t, os.MkdirAll("./testdata/acceptance/tmp", 0o700))
config, err := nfpm.ParseFile("./testdata/acceptance/config-noreplace-old.yaml")
config, err := nfpm.ParseFile("./testdata/acceptance/rpm.config-noreplace-old.yaml")
require.NoError(t, err)
info, err := config.Get("rpm")
@ -99,188 +83,136 @@ func TestConfigNoReplace(t *testing.T) {
require.NoError(t, err)
info.Target = target
require.NoError(t, pkg.Package(nfpm.WithDefaults(info), f))
t.Run("rpm", func(t *testing.T) {
t.Run("rpm/config-noreplace", func(t *testing.T) {
accept(t, acceptParms{
Name: "noreplace_rpm",
Conf: "config-noreplace.yaml",
Format: "rpm",
Dockerfile: "rpm.config-noreplace.dockerfile",
Name: "noreplace_rpm",
Conf: "rpm.config-noreplace.yaml",
Format: "rpm",
Docker: dockerParams{
File: "rpm.dockerfile",
Target: "config-noreplace",
Arch: "amd64",
},
})
})
}
func TestEnvVarVersion(t *testing.T) {
for _, format := range formats {
format := format
t.Run(fmt.Sprintf("amd64-%s", format), func(t *testing.T) {
os.Setenv("SEMVER", "v1.0.0-0.1.b1+git.abcdefgh")
accept(t, acceptParms{
Name: fmt.Sprintf("env-var-version_%s", format),
Conf: "env-var-version.yaml",
Format: format,
Dockerfile: fmt.Sprintf("%s.env-var-version.dockerfile", format),
})
})
}
}
func TestComplexOverrides(t *testing.T) {
for _, format := range formats {
format := format
t.Run(fmt.Sprintf("amd64-%s", format), func(t *testing.T) {
accept(t, acceptParms{
Name: fmt.Sprintf("overrides_%s", format),
Conf: "overrides.yaml",
Format: format,
Dockerfile: fmt.Sprintf("%s.overrides.dockerfile", format),
})
})
}
}
func TestMin(t *testing.T) {
for _, format := range formats {
format := format
t.Run(fmt.Sprintf("amd64-%s", format), func(t *testing.T) {
accept(t, acceptParms{
Name: fmt.Sprintf("min_%s", format),
Conf: "min.yaml",
Format: format,
Dockerfile: fmt.Sprintf("%s.min.dockerfile", format),
})
})
}
}
func TestMeta(t *testing.T) {
for _, format := range formats {
format := format
t.Run(fmt.Sprintf("amd64-%s", format), func(t *testing.T) {
accept(t, acceptParms{
Name: fmt.Sprintf("meta_%s", format),
Conf: "meta.yaml",
Format: format,
Dockerfile: fmt.Sprintf("%s.meta.dockerfile", format),
})
})
}
}
func TestRPMCompression(t *testing.T) {
func TestCompression(t *testing.T) {
t.Parallel()
format := "rpm"
compressFormats := []string{"gzip", "xz", "lzma"}
for _, format := range compressFormats {
format := format
t.Run(format, func(t *testing.T) {
accept(t, acceptParms{
Name: fmt.Sprintf("%s_compression_rpm", format),
Conf: fmt.Sprintf("%s.compression.yaml", format),
Format: "rpm",
Dockerfile: fmt.Sprintf("%s.rpm.compression.dockerfile", format),
})
})
for _, arch := range formatArchs[format] {
for _, compFormat := range compressFormats {
func(tt *testing.T, testCompFormat, testArch string) {
tt.Run(fmt.Sprintf("%s/%s/%s", format, testArch, testCompFormat), func(ttt *testing.T) {
ttt.Parallel()
if testArch == "ppc64le" && os.Getenv("NO_TEST_PPC64LE") == "true" {
ttt.Skip("ppc64le arch not supported in pipeline")
}
accept(ttt, acceptParms{
Name: fmt.Sprintf("%s_compression_%s", testCompFormat, testArch),
Conf: fmt.Sprintf("rpm.%s.compression.yaml", testCompFormat),
Format: format,
Docker: dockerParams{
File: fmt.Sprintf("%s.dockerfile", format),
Target: "compression",
Arch: testArch,
BuildArgs: []string{fmt.Sprintf("compression=%s", testCompFormat)},
},
})
})
}(t, compFormat, arch)
}
}
}
func TestRPMRelease(t *testing.T) {
accept(t, acceptParms{
Name: "release_rpm",
Conf: "release.rpm.yaml",
Format: "rpm",
Dockerfile: "release.rpm.dockerfile",
})
}
func TestDebRules(t *testing.T) {
accept(t, acceptParms{
Name: "rules.deb",
Conf: "rules.deb.yaml",
Format: "deb",
Dockerfile: "rules.deb.dockerfile",
})
}
func TestChangelog(t *testing.T) {
for _, format := range formats {
format := format
t.Run(fmt.Sprintf("changelog-%s", format), func(t *testing.T) {
accept(t, acceptParms{
Name: fmt.Sprintf("changelog_%s", format),
Conf: "withchangelog.yaml",
Format: format,
Dockerfile: fmt.Sprintf("%s.changelog.dockerfile", format),
})
})
func TestRPMSpecific(t *testing.T) {
t.Parallel()
format := "rpm"
testNames := []string{
"release",
}
for _, name := range testNames {
for _, arch := range formatArchs[format] {
func(tt *testing.T, testName, testArch string) {
tt.Run(fmt.Sprintf("%s/%s/%s", format, testArch, testName), func(ttt *testing.T) {
ttt.Parallel()
if testArch == "ppc64le" && os.Getenv("NO_TEST_PPC64LE") == "true" {
ttt.Skip("ppc64le arch not supported in pipeline")
}
accept(ttt, acceptParms{
Name: fmt.Sprintf("%s_%s", testName, testArch),
Conf: fmt.Sprintf("%s.%s.yaml", format, testName),
Format: format,
Docker: dockerParams{
File: fmt.Sprintf("%s.dockerfile", format),
Target: testName,
Arch: testArch,
},
})
})
}(t, name, arch)
}
}
}
func TestDebTriggers(t *testing.T) {
t.Run("triggers-deb", func(t *testing.T) {
accept(t, acceptParms{
Name: "triggers-deb",
Conf: "triggers.yaml",
Format: "deb",
Dockerfile: "deb.triggers.dockerfile",
})
})
}
func TestSymlink(t *testing.T) {
for _, format := range formats {
format := format
t.Run(fmt.Sprintf("symlink-%s", format), func(t *testing.T) {
accept(t, acceptParms{
Name: fmt.Sprintf("symlink_%s", format),
Conf: "symlink.yaml",
Format: format,
Dockerfile: fmt.Sprintf("%s.symlink.dockerfile", format),
})
})
func TestDebSpecific(t *testing.T) {
t.Parallel()
format := "deb"
testNames := []string{
"rules",
"triggers",
"breaks",
}
}
func TestDebBreaks(t *testing.T) {
t.Run("breaks-deb", func(t *testing.T) {
accept(t, acceptParms{
Name: "breaks-deb",
Conf: "breaks.yaml",
Format: "deb",
Dockerfile: "deb.breaks.dockerfile",
})
})
}
func TestSignatures(t *testing.T) {
for _, format := range formats {
format := format
t.Run("signed", func(t *testing.T) {
accept(t, acceptParms{
Name: fmt.Sprintf("signed_%s", format),
Conf: "signed.yaml",
Format: format,
Dockerfile: fmt.Sprintf("%s.signed.dockerfile", format),
})
})
for _, name := range testNames {
for _, arch := range formatArchs[format] {
func(tt *testing.T, testName, testArch string) {
tt.Run(fmt.Sprintf("%s/%s/%s", format, testArch, testName), func(ttt *testing.T) {
ttt.Parallel()
if testArch == "ppc64le" && os.Getenv("NO_TEST_PPC64LE") == "true" {
ttt.Skip("ppc64le arch not supported in pipeline")
}
accept(ttt, acceptParms{
Name: fmt.Sprintf("%s_%s", testName, testArch),
Conf: fmt.Sprintf("%s.%s.yaml", format, testName),
Format: format,
Docker: dockerParams{
File: fmt.Sprintf("%s.dockerfile", format),
Target: testName,
Arch: testArch,
},
})
})
}(t, name, arch)
}
}
}
type acceptParms struct {
Name string
Conf string
Format string
Dockerfile string
Name string
Conf string
Format string
Docker dockerParams
}
type dockerParams struct {
File string
Target string
Arch string
BuildArgs []string
}
type testWriter struct {
t *testing.T
*testing.T
}
func (t testWriter) Write(p []byte) (n int, err error) {
t.t.Log(string(p))
t.Log(string(p))
return len(p), nil
}
func accept(t *testing.T, params acceptParms) {
t.Helper()
configFile := filepath.Join("./testdata/acceptance/", params.Conf)
tmp, err := filepath.Abs("./testdata/acceptance/tmp")
require.NoError(t, err)
@ -290,7 +222,17 @@ func accept(t *testing.T, params acceptParms) {
require.NoError(t, os.MkdirAll(tmp, 0o700))
config, err := nfpm.ParseFile(configFile)
envFunc := func(s string) string {
switch s {
case "BUILD_ARCH":
return params.Docker.Arch
case "SEMVER":
return "v1.0.0-0.1.b1+git.abcdefgh"
default:
return os.Getenv(s)
}
}
config, err := nfpm.ParseFileWithEnvMapping(configFile, envFunc)
require.NoError(t, err)
info, err := config.Get(params.Format)
@ -300,21 +242,28 @@ func accept(t *testing.T, params acceptParms) {
pkg, err := nfpm.Get(params.Format)
require.NoError(t, err)
cmdArgs := []string{
"build", "--rm", "--force-rm",
"--platform", fmt.Sprintf("linux/%s", params.Docker.Arch),
"-f", params.Docker.File,
"--target", params.Docker.Target,
"--build-arg", "package=" + filepath.Join("tmp", packageName),
}
for _, arg := range params.Docker.BuildArgs {
cmdArgs = append(cmdArgs, "--build-arg", arg)
}
cmdArgs = append(cmdArgs, ".")
f, err := os.Create(target)
require.NoError(t, err)
info.Target = target
require.NoError(t, pkg.Package(nfpm.WithDefaults(info), f))
//nolint:gosec
cmd := exec.Command(
os.Getenv("CONTAINER_RUNTIME"), "build", "--rm", "--force-rm",
"-f", params.Dockerfile,
"--build-arg", "package="+filepath.Join("tmp", packageName),
".",
)
cmd := exec.Command("docker", cmdArgs...)
cmd.Dir = "./testdata/acceptance"
cmd.Stderr = testWriter{t}
cmd.Stdout = cmd.Stderr
t.Log("will exec:", cmd.Args)
t.Log("will exec:", cmd.Args, "with env BUILD_ARCH:", envFunc("BUILD_ARCH"))
require.NoError(t, cmd.Run())
}

View File

@ -130,7 +130,7 @@ func ExpandContentGlobs(contents Contents, disableGlobbing bool) (files Contents
continue
}
var options []fileglob.OptFunc
options := []fileglob.OptFunc{fileglob.MatchDirectoryIncludesContents}
if disableGlobbing {
options = append(options, fileglob.QuoteMeta)
}

View File

@ -7,7 +7,6 @@ import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v3"
@ -35,11 +34,60 @@ contents:
dec.KnownFields(true)
err := dec.Decode(&config)
require.NoError(t, err)
assert.Len(t, config.Contents, 2)
require.Len(t, config.Contents, 2)
for _, f := range config.Contents {
t.Logf("%+#v\n", f)
assert.Equal(t, f.Source, "a")
assert.Equal(t, f.Destination, "b")
require.Equal(t, f.Source, "a")
require.Equal(t, f.Destination, "b")
}
}
func TestDeepPathsWithGlob(t *testing.T) {
var config testStruct
dec := yaml.NewDecoder(strings.NewReader(`---
contents:
- src: testdata/globtest/**/*
dst: /bla
file_info:
mode: 0644
mtime: 2008-01-02T15:04:05Z
`))
dec.KnownFields(true)
err := dec.Decode(&config)
require.NoError(t, err)
require.Len(t, config.Contents, 1)
parsedContents, err := files.ExpandContentGlobs(config.Contents, false)
require.NoError(t, err)
for _, f := range parsedContents {
switch f.Source {
case "testdata/globtest/nested/b.txt":
require.Equal(t, "/bla/nested/b.txt", f.Destination)
case "testdata/globtest/multi-nested/subdir/c.txt":
require.Equal(t, "/bla/multi-nested/subdir/c.txt", f.Destination)
}
}
}
func TestDeepPathsWithoutGlob(t *testing.T) {
var config testStruct
dec := yaml.NewDecoder(strings.NewReader(`---
contents:
- src: testdata/deep-paths/
dst: /bla
`))
dec.KnownFields(true)
err := dec.Decode(&config)
require.NoError(t, err)
require.Len(t, config.Contents, 1)
parsedContents, err := files.ExpandContentGlobs(config.Contents, true)
require.NoError(t, err)
for _, f := range parsedContents {
switch f.Source {
case "testdata/deep-paths/nested1/nested2/a.txt":
require.Equal(t, "/bla/nested1/nested2/a.txt", f.Destination)
default:
t.Errorf("unknown source %s", f.Source)
}
}
}
@ -56,16 +104,16 @@ contents:
config.Contents, err = files.ExpandContentGlobs(config.Contents, true)
require.NoError(t, err)
assert.Len(t, config.Contents, 1)
require.Len(t, config.Contents, 1)
fi, err := os.Stat("files_test.go")
require.NoError(t, err)
f := config.Contents[0]
assert.Equal(t, f.Source, "files_test.go")
assert.Equal(t, f.Destination, "b")
assert.Equal(t, f.FileInfo.Mode, fi.Mode())
assert.Equal(t, f.FileInfo.MTime, fi.ModTime())
require.Equal(t, f.Source, "files_test.go")
require.Equal(t, f.Destination, "b")
require.Equal(t, f.FileInfo.Mode, fi.Mode())
require.Equal(t, f.FileInfo.MTime, fi.ModTime())
}
func TestFileInfo(t *testing.T) {
@ -86,16 +134,16 @@ contents:
config.Contents, err = files.ExpandContentGlobs(config.Contents, true)
require.NoError(t, err)
assert.Len(t, config.Contents, 1)
require.Len(t, config.Contents, 1)
ct, err := time.Parse(time.RFC3339, "2008-01-02T15:04:05Z")
require.NoError(t, err)
f := config.Contents[0]
assert.Equal(t, f.Source, "files_test.go")
assert.Equal(t, f.Destination, "b")
assert.Equal(t, f.FileInfo.Mode, os.FileMode(0o123))
assert.Equal(t, f.FileInfo.MTime, ct)
require.Equal(t, f.Source, "files_test.go")
require.Equal(t, f.Destination, "b")
require.Equal(t, f.FileInfo.Mode, os.FileMode(0o123))
require.Equal(t, f.FileInfo.MTime, ct)
}
func TestRace(t *testing.T) {

View File

0
files/testdata/globtest/a.txt vendored Normal file
View File

View File

0
files/testdata/globtest/nested/b.txt vendored Normal file
View File

6
go.mod
View File

@ -20,7 +20,7 @@ require (
github.com/goreleaser/fileglob v1.2.0
github.com/imdario/mergo v0.3.12
github.com/kevinburke/ssh_config v1.1.0 // indirect
github.com/mitchellh/copystructure v1.1.1 // indirect
github.com/mitchellh/copystructure v1.1.2 // indirect
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 // indirect
github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b
github.com/sergi/go-diff v1.2.0 // indirect
@ -28,8 +28,8 @@ require (
github.com/ulikunitz/xz v0.5.9 // indirect
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 // indirect
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1 // indirect
golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
)

15
go.sum
View File

@ -203,8 +203,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/copystructure v1.1.1 h1:Bp6x9R1Wn16SIz3OfeDr0b7RnCG2OB66Y7PQyC/cvq4=
github.com/mitchellh/copystructure v1.1.1/go.mod h1:EBArHfARyrSWO/+Wyr9zwEkc6XMFB9XyNgFNmRkZZU4=
github.com/mitchellh/copystructure v1.1.2 h1:Th2TIvG1+6ma3e/0/bopBKohOTY7s4dA8V2q4EUcBJ0=
github.com/mitchellh/copystructure v1.1.2/go.mod h1:EBArHfARyrSWO/+Wyr9zwEkc6XMFB9XyNgFNmRkZZU4=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
@ -352,8 +352,8 @@ golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1 h1:4qWs8cYYH6PoEFy4dfhDFgoMGkwAcETd+MmPdCPMzUc=
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -387,8 +387,8 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750 h1:ZBu6861dZq7xBnG1bn5SRU0vA8nx42at4+kP07FMTog=
golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@ -396,8 +396,9 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

View File

@ -6,6 +6,7 @@ import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/goreleaser/fileglob"
)
@ -51,6 +52,13 @@ func (e ErrGlobNoMatch) Error() string {
// First the longest common prefix (lcp) of all globbed files is found. The destination
// for each globbed file is then dst joined with src with the lcp trimmed off.
func Glob(pattern, dst string, options ...fileglob.OptFunc) (map[string]string, error) {
if strings.HasPrefix(pattern, "../") {
p, err := filepath.Abs(pattern)
if err != nil {
return nil, fmt.Errorf("failed to resolve pattern: %s: %w", pattern, err)
}
pattern = filepath.ToSlash(p)
}
matches, err := fileglob.Glob(pattern, append(options, fileglob.MaybeRootFS)...)
if errors.Is(err, os.ErrNotExist) {
return nil, err
@ -63,11 +71,12 @@ func Glob(pattern, dst string, options ...fileglob.OptFunc) (map[string]string,
return nil, ErrGlobNoMatch{pattern}
}
files := make(map[string]string)
prefix := longestCommonPrefix(matches)
prefix := pattern
// the prefix may not be a complete path or may use glob patterns, in that case use the parent directory
if _, err := os.Stat(prefix); os.IsNotExist(err) || fileglob.ContainsMatchers(pattern) {
prefix = filepath.Dir(prefix)
prefix = filepath.Dir(longestCommonPrefix(matches))
}
for _, src := range matches {
// only include files
if f, err := os.Stat(src); err == nil && f.Mode().IsDir() {

94
nfpm.go
View File

@ -57,11 +57,20 @@ func Get(format string) (Packager, error) {
// Parse decodes YAML data from an io.Reader into a configuration struct.
func Parse(in io.Reader) (config Config, err error) {
return ParseWithEnvMapping(in, os.Getenv)
}
// ParseWithEnvMapping decodes YAML data from an io.Reader into a configuration struct.
func ParseWithEnvMapping(in io.Reader, mapping func(string) string) (config Config, err error) {
dec := yaml.NewDecoder(in)
dec.KnownFields(true)
if err = dec.Decode(&config); err != nil {
return
}
config.envMappingFunc = mapping
if config.envMappingFunc == nil {
config.envMappingFunc = func(s string) string { return s }
}
config.expandEnvVars()
@ -70,51 +79,20 @@ func Parse(in io.Reader) (config Config, err error) {
return config, config.Validate()
}
func (c *Config) expandEnvVars() {
// Version related fields
c.Info.Release = os.ExpandEnv(c.Info.Release)
c.Info.Version = os.ExpandEnv(c.Info.Version)
c.Info.Prerelease = os.ExpandEnv(c.Info.Prerelease)
// Package signing related fields
c.Info.Deb.Signature.KeyFile = os.ExpandEnv(c.Deb.Signature.KeyFile)
c.Info.RPM.Signature.KeyFile = os.ExpandEnv(c.RPM.Signature.KeyFile)
c.Info.APK.Signature.KeyFile = os.ExpandEnv(c.APK.Signature.KeyFile)
c.Info.Deb.Signature.KeyID = pointer.ToString(os.ExpandEnv(pointer.GetString(c.Deb.Signature.KeyID)))
c.Info.RPM.Signature.KeyID = pointer.ToString(os.ExpandEnv(pointer.GetString(c.RPM.Signature.KeyID)))
c.Info.APK.Signature.KeyID = pointer.ToString(os.ExpandEnv(pointer.GetString(c.APK.Signature.KeyID)))
// Package signing passphrase
generalPassphrase := os.ExpandEnv("$NFPM_PASSPHRASE")
c.Info.Deb.Signature.KeyPassphrase = generalPassphrase
c.Info.RPM.Signature.KeyPassphrase = generalPassphrase
c.Info.APK.Signature.KeyPassphrase = generalPassphrase
debPassphrase := os.ExpandEnv("$NFPM_DEB_PASSPHRASE")
if debPassphrase != "" {
c.Info.Deb.Signature.KeyPassphrase = debPassphrase
}
rpmPassphrase := os.ExpandEnv("$NFPM_RPM_PASSPHRASE")
if rpmPassphrase != "" {
c.Info.RPM.Signature.KeyPassphrase = rpmPassphrase
}
apkPassphrase := os.ExpandEnv("$NFPM_APK_PASSPHRASE")
if apkPassphrase != "" {
c.Info.APK.Signature.KeyPassphrase = apkPassphrase
}
}
// ParseFile decodes YAML data from a file path into a configuration struct.
func ParseFile(path string) (config Config, err error) {
return ParseFileWithEnvMapping(path, os.Getenv)
}
// ParseFileWithEnvMapping decodes YAML data from a file path into a configuration struct.
func ParseFileWithEnvMapping(path string, mapping func(string) string) (config Config, err error) {
var file *os.File
file, err = os.Open(path) //nolint:gosec
if err != nil {
return
}
defer file.Close() // nolint: errcheck,gosec
return Parse(file)
return ParseWithEnvMapping(file, mapping)
}
// Packager represents any packager implementation.
@ -125,8 +103,9 @@ type Packager interface {
// Config contains the top level configuration for packages.
type Config struct {
Info `yaml:",inline"`
Overrides map[string]Overridables `yaml:"overrides,omitempty"`
Info `yaml:",inline"`
Overrides map[string]Overridables `yaml:"overrides,omitempty"`
envMappingFunc func(string) string
}
// Get returns the Info struct for the given packager format. Overrides
@ -168,6 +147,43 @@ func (c *Config) Validate() error {
return nil
}
func (c *Config) expandEnvVars() {
// Version related fields
c.Info.Release = os.Expand(c.Info.Release, c.envMappingFunc)
c.Info.Version = os.Expand(c.Info.Version, c.envMappingFunc)
c.Info.Prerelease = os.Expand(c.Info.Prerelease, c.envMappingFunc)
c.Info.Arch = os.Expand(c.Info.Arch, c.envMappingFunc)
// Package signing related fields
c.Info.Deb.Signature.KeyFile = os.Expand(c.Deb.Signature.KeyFile, c.envMappingFunc)
c.Info.RPM.Signature.KeyFile = os.Expand(c.RPM.Signature.KeyFile, c.envMappingFunc)
c.Info.APK.Signature.KeyFile = os.Expand(c.APK.Signature.KeyFile, c.envMappingFunc)
c.Info.Deb.Signature.KeyID = pointer.ToString(os.Expand(pointer.GetString(c.Deb.Signature.KeyID), c.envMappingFunc))
c.Info.RPM.Signature.KeyID = pointer.ToString(os.Expand(pointer.GetString(c.RPM.Signature.KeyID), c.envMappingFunc))
c.Info.APK.Signature.KeyID = pointer.ToString(os.Expand(pointer.GetString(c.APK.Signature.KeyID), c.envMappingFunc))
// Package signing passphrase
generalPassphrase := os.Expand("$NFPM_PASSPHRASE", c.envMappingFunc)
c.Info.Deb.Signature.KeyPassphrase = generalPassphrase
c.Info.RPM.Signature.KeyPassphrase = generalPassphrase
c.Info.APK.Signature.KeyPassphrase = generalPassphrase
debPassphrase := os.Expand("$NFPM_DEB_PASSPHRASE", c.envMappingFunc)
if debPassphrase != "" {
c.Info.Deb.Signature.KeyPassphrase = debPassphrase
}
rpmPassphrase := os.Expand("$NFPM_RPM_PASSPHRASE", c.envMappingFunc)
if rpmPassphrase != "" {
c.Info.RPM.Signature.KeyPassphrase = rpmPassphrase
}
apkPassphrase := os.Expand("$NFPM_APK_PASSPHRASE", c.envMappingFunc)
if apkPassphrase != "" {
c.Info.APK.Signature.KeyPassphrase = apkPassphrase
}
}
// Info contains information about a single package.
type Info struct {
Overridables `yaml:",inline"`

View File

@ -171,22 +171,31 @@ func TestParseEnhancedFile(t *testing.T) {
require.NoError(t, err)
require.Equal(t, config.Name, "contents foo")
shouldFind := 5
if len(config.Contents) != shouldFind {
t.Errorf("should have had %d files but found %d", shouldFind, len(config.Contents))
for idx, f := range config.Contents {
t.Logf("%d => %+#v\n", idx, f)
}
}
require.Len(t, config.Contents, shouldFind)
}
func TestParseEnhancedNestedGlobFile(t *testing.T) {
config, err := nfpm.ParseFile("./testdata/contents_glob.yaml")
require.NoError(t, err)
shouldFind := 3
if len(config.Contents) != shouldFind {
t.Errorf("should have had %d files but found %d", shouldFind, len(config.Contents))
for idx, f := range config.Contents {
t.Logf("%d => %+#v\n", idx, f)
require.Len(t, config.Contents, shouldFind)
}
func TestParseEnhancedNestedNoGlob(t *testing.T) {
config, err := nfpm.ParseFile("./testdata/contents_directory.yaml")
require.NoError(t, err)
shouldFind := 3
require.Len(t, config.Contents, shouldFind)
for _, f := range config.Contents {
switch f.Source {
case "testdata/globtest/nested/b.txt":
require.Equal(t, "/etc/foo/nested/b.txt", f.Destination)
case "testdata/globtest/multi-nested/subdir/c.txt":
require.Equal(t, "/etc/foo/multi-nested/subdir/c.txt", f.Destination)
case "testdata/globtest/a.txt":
require.Equal(t, "/etc/foo/a.txt", f.Destination)
default:
t.Errorf("unknown source %s", f.Source)
}
}
}

View File

@ -1,27 +0,0 @@
FROM alpine
ARG package
COPY ${package} /tmp/foo.apk
RUN apk add --allow-untrusted /tmp/foo.apk
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN test -d /usr/share/whatever/
RUN test -d /usr/share/whatever/folder
RUN test -f /usr/share/whatever/folder/file1
RUN test -f /usr/share/whatever/folder/file2
RUN test -d /usr/share/whatever/folder/folder2
RUN test -f /usr/share/whatever/folder/folder2/file1
RUN test -f /usr/share/whatever/folder/folder2/file2
RUN test -d /usr/share/foo
RUN test -d /usr/share/whatever
RUN test -f /tmp/preinstall-proof
RUN test -f /tmp/postinstall-proof
RUN test ! -f /tmp/preremove-proof
RUN test ! -f /tmp/postremove-proof
RUN echo wat >> /etc/foo/whatever.conf
RUN apk del foo
RUN test -f /etc/foo/whatever.conf
RUN test ! -f /usr/local/bin/fake
RUN test -f /tmp/preremove-proof
RUN test -f /tmp/postremove-proof
RUN test ! -d /usr/share/foo
RUN test ! -d /usr/share/whatever

View File

@ -1,10 +0,0 @@
FROM alpine
ARG package
COPY ${package} /tmp/foo.apk
RUN apk add --allow-untrusted /tmp/foo.apk
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN echo wat >> /etc/foo/whatever.conf
RUN apk del foo
RUN test -f /etc/foo/whatever.conf
RUN test ! -f /usr/local/bin/fake

View File

@ -1,10 +0,0 @@
FROM alpine
ARG package
COPY ${package} /tmp/foo.apk
RUN apk add --allow-untrusted /tmp/foo.apk
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN echo wat >> /etc/foo/whatever.conf
RUN apk del foo
RUN test -f /etc/foo/whatever.conf
RUN test ! -f /usr/local/bin/fake

View File

@ -1,5 +0,0 @@
FROM alpine
ARG package
COPY ${package} /tmp/foo.apk
RUN apk add --allow-untrusted /tmp/foo.apk
# TODO: seems like there is no changelog support on apk

View File

@ -1,27 +0,0 @@
FROM alpine
ARG package
COPY ${package} /tmp/foo.apk
RUN apk add --allow-untrusted /tmp/foo.apk
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN test -d /usr/share/whatever/
RUN test -d /usr/share/whatever/folder
RUN test -f /usr/share/whatever/folder/file1
RUN test -f /usr/share/whatever/folder/file2
RUN test -d /usr/share/whatever/folder/folder2
RUN test -f /usr/share/whatever/folder/folder2/file1
RUN test -f /usr/share/whatever/folder/folder2/file2
RUN test -d /var/log/whatever
RUN test -d /usr/share/foo
RUN test -f /tmp/preinstall-proof
RUN test -f /tmp/postinstall-proof
RUN test ! -f /tmp/preremove-proof
RUN test ! -f /tmp/postremove-proof
RUN echo wat >> /etc/foo/whatever.conf
RUN apk del foo
RUN test -f /etc/foo/whatever.conf
RUN test ! -f /usr/local/bin/fake
RUN test -f /tmp/preremove-proof
RUN test -f /tmp/postremove-proof
RUN test ! -d /var/log/whatever
RUN test ! -d /usr/share/foo

View File

@ -1,10 +1,104 @@
FROM alpine
FROM alpine AS test_base
ARG package
RUN echo "${package}"
COPY ${package} /tmp/foo.apk
# ---- minimal test ----
FROM test_base AS min
RUN apk add --allow-untrusted /tmp/foo.apk
# ---- symlink test ----
FROM min AS symlink
RUN ls -l /path/to/symlink | grep "/path/to/symlink -> /etc/foo/whatever.conf"
# ---- simple test ----
FROM min AS simple
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN echo wat >> /etc/foo/whatever.conf
RUN apk del foo
RUN test -f /etc/foo/whatever.conf
RUN test ! -f /usr/local/bin/fake
# ---- no-glob test ----
FROM min AS no-glob
RUN test -d /usr/share/whatever/
RUN test -f /usr/share/whatever/file1
RUN test -f /usr/share/whatever/file2
RUN test -d /usr/share/whatever/folder2
RUN test -f /usr/share/whatever/folder2/file1
RUN test -f /usr/share/whatever/folder2/file2
# ---- complex test ----
FROM min AS complex
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN test -d /usr/share/whatever/
RUN test -d /usr/share/whatever/folder
RUN test -f /usr/share/whatever/folder/file1
RUN test -f /usr/share/whatever/folder/file2
RUN test -d /usr/share/whatever/folder/folder2
RUN test -f /usr/share/whatever/folder/folder2/file1
RUN test -f /usr/share/whatever/folder/folder2/file2
RUN test -d /var/log/whatever
RUN test -d /usr/share/foo
RUN test -f /tmp/preinstall-proof
RUN test -f /tmp/postinstall-proof
RUN test ! -f /tmp/preremove-proof
RUN test ! -f /tmp/postremove-proof
RUN echo wat >> /etc/foo/whatever.conf
RUN apk del foo
RUN test -f /etc/foo/whatever.conf
RUN test ! -f /usr/local/bin/fake
RUN test -f /tmp/preremove-proof
RUN test -f /tmp/postremove-proof
RUN test ! -d /var/log/whatever
RUN test ! -d /usr/share/foo
# ---- signed test ----
FROM test_base AS signed
COPY keys/rsa_unprotected.pub /etc/apk/keys/john@example.com.rsa.pub
RUN apk verify /tmp/foo.apk | grep "/tmp/foo.apk: 0 - OK"
RUN apk add /tmp/foo.apk
# ---- overrides test ----
FROM min AS overrides
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN test ! -f /tmp/preinstall-proof
RUN test -f /tmp/postinstall-proof
RUN test ! -f /tmp/preremove-proof
RUN test ! -f /tmp/postremove-proof
RUN echo wat >> /etc/foo/whatever.conf
RUN apk del foo
RUN test -f /etc/foo/whatever.conf
RUN test ! -f /usr/local/bin/fake
RUN test -f /tmp/preremove-proof
RUN test ! -f /tmp/postremove-proof
# ---- meta test ----
FROM min AS meta
RUN command -v zsh
RUN command -v fish
# ---- env-var-version test ----
FROM min AS env-var-version
ENV EXPECTVER="foo-1.0.0~0.1.b1+git.abcdefgh description:"
RUN apk info foo | grep "foo-" | grep " description:" > found
RUN export FOUND_VER="$(cat found)" && \
echo "Expected: '${EXPECTVER}' :: Found: '${FOUND_VER}'" && \
test "${FOUND_VER}" = "${EXPECTVER}"
# ---- changelog test ----
FROM min AS withchangelog
RUN echo "No Changelog support for apk?"

View File

@ -1,9 +0,0 @@
FROM alpine
ARG package
COPY ${package} /tmp/foo.apk
RUN apk add --allow-untrusted /tmp/foo.apk
ENV EXPECTVER="foo-1.0.0~0.1.b1+git.abcdefgh description:"
RUN apk info foo | grep "foo-" | grep " description:" > found
RUN export FOUND_VER="$(cat found)" && \
echo "Expected: '${EXPECTVER}' :: Found: '${FOUND_VER}'" && \
test "${FOUND_VER}" = "${EXPECTVER}"

View File

@ -1,6 +0,0 @@
FROM alpine
ARG package
COPY ${package} /tmp/foo.apk
RUN apk add --allow-untrusted /tmp/foo.apk
RUN command -v zsh
RUN command -v fish

View File

@ -1,4 +0,0 @@
FROM alpine
ARG package
COPY ${package} /tmp/foo.apk
RUN apk add --allow-untrusted /tmp/foo.apk

View File

@ -1,16 +0,0 @@
FROM alpine
ARG package
COPY ${package} /tmp/foo.apk
RUN apk add -vvv --allow-untrusted /tmp/foo.apk
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN test ! -f /tmp/preinstall-proof
RUN test -f /tmp/postinstall-proof
RUN test ! -f /tmp/preremove-proof
RUN test ! -f /tmp/postremove-proof
RUN echo wat >> /etc/foo/whatever.conf
RUN apk del foo
RUN test -f /etc/foo/whatever.conf
RUN test ! -f /usr/local/bin/fake
RUN test -f /tmp/preremove-proof
RUN test ! -f /tmp/postremove-proof

View File

@ -1,10 +0,0 @@
FROM alpine
ARG package
COPY ${package} /tmp/foo.apk
RUN apk add --allow-untrusted /tmp/foo.apk
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN echo wat >> /etc/foo/whatever.conf
RUN apk del foo
RUN test -f /etc/foo/whatever.conf
RUN test ! -f /usr/local/bin/fake

View File

@ -1,7 +0,0 @@
FROM alpine
ARG package
COPY keys/rsa_unprotected.pub /etc/apk/keys/john@example.com.rsa.pub
COPY ${package} /tmp/foo.apk
RUN apk verify /tmp/foo.apk | grep "/tmp/foo.apk: 0 - OK"
RUN apk add /tmp/foo.apk

View File

@ -1,5 +0,0 @@
FROM alpine
ARG package
COPY ${package} /tmp/foo.apk
RUN apk add --allow-untrusted /tmp/foo.apk
RUN ls -l /path/to/symlink | grep "/path/to/symlink -> /etc/foo/whatever.conf"

View File

@ -1,36 +0,0 @@
name: "foo"
arch: "386"
platform: "linux"
version: "v1.2.3-beta"
maintainer: "Foo Bar"
depends:
- bash
provides:
- fake
replaces:
- foo
suggests:
- zsh
description: |
Foo bar
Multiple lines
vendor: "foobar"
homepage: "https://foobar.org"
license: "MIT"
contents:
- src: ./testdata/fake
dst: /usr/local/bin/fake
- src: ./testdata/acceptance/folder/*
dst: /usr/share/whatever/folder/
- src: ./testdata/whatever.conf
dst: /etc/foo/whatever.conf
type: config
empty_folders:
- /var/log/whatever
- /usr/share/foo
scripts:
preinstall: ./testdata/acceptance/scripts/preinstall.sh
postinstall: ./testdata/acceptance/scripts/postinstall.sh
preremove: ./testdata/acceptance/scripts/preremove.sh
postremove: ./testdata/acceptance/scripts/postremove.sh

View File

@ -1,5 +1,5 @@
name: "foo"
arch: "amd64"
arch: "${BUILD_ARCH}"
platform: "linux"
version: "v1.2.3-beta"
maintainer: "Foo Bar"

View File

@ -1,5 +1,5 @@
name: "foo"
arch: "amd64"
arch: "${BUILD_ARCH}"
platform: "linux"
version: "${SEMVER}"
maintainer: "Foo Bar"

View File

@ -1,5 +1,5 @@
name: "foo"
arch: "amd64"
arch: "${BUILD_ARCH}"
platform: "linux"
version: "v1.2.3-beta"
maintainer: "Foo Bar"

View File

@ -1,7 +1,8 @@
name: foo
arch: amd64
arch: "${BUILD_ARCH}"
version: 1.2.3
license: MIT
maintainer: "Foo Bar"
contents:
- src: ./testdata/fake
dst: /usr/local/bin/fake

11
testdata/acceptance/core.no-glob.yaml vendored Normal file
View File

@ -0,0 +1,11 @@
name: "foo"
arch: "${BUILD_ARCH}"
platform: "linux"
version: "v1.2.3-beta"
maintainer: "Foo Bar"
vendor: "foobar"
homepage: "https://foobar.org"
license: "MIT"
contents:
- src: ./testdata/acceptance/folder
dst: /usr/share/whatever

View File

@ -1,5 +1,5 @@
name: "foo"
arch: "amd64"
arch: "${BUILD_ARCH}"
platform: "linux"
version: "v1.2.3-beta"
maintainer: "Foo Bar"

View File

@ -1,5 +1,5 @@
name: "foo"
arch: "amd64"
arch: "${BUILD_ARCH}"
platform: "linux"
version: "v1.0.0"
maintainer: "John Doe <john@example.com>"

View File

@ -1,5 +1,5 @@
name: "foo"
arch: "amd64"
arch: "${BUILD_ARCH}"
platform: "linux"
version: "v1.2.3"
release: "simple"

View File

@ -1,5 +1,5 @@
name: "foo"
arch: "amd64"
arch: "${BUILD_ARCH}"
platform: "linux"
version: "v1.2.3"
maintainer: "Foo Bar"

View File

@ -1,5 +1,5 @@
name: "foo"
arch: "amd64"
arch: "${BUILD_ARCH}"
platform: "linux"
changelog: "./testdata/changelog.yaml"
version: "v1.2.3"

View File

@ -1,27 +0,0 @@
FROM i386/ubuntu
ARG package
COPY ${package} /tmp/foo.deb
RUN dpkg -i /tmp/foo.deb
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN test -d /usr/share/whatever/
RUN test -d /usr/share/whatever/folder
RUN test -f /usr/share/whatever/folder/file1
RUN test -f /usr/share/whatever/folder/file2
RUN test -d /usr/share/whatever/folder/folder2
RUN test -f /usr/share/whatever/folder/folder2/file1
RUN test -f /usr/share/whatever/folder/folder2/file2
RUN test -d /usr/share/foo
RUN test -d /usr/share/whatever
RUN test -f /tmp/preinstall-proof
RUN test -f /tmp/postinstall-proof
RUN test ! -f /tmp/preremove-proof
RUN test ! -f /tmp/postremove-proof
RUN echo wat >> /etc/foo/whatever.conf
RUN dpkg -r foo
RUN test -f /etc/foo/whatever.conf
RUN test ! -f /usr/local/bin/fake
RUN test -f /tmp/preremove-proof
RUN test -f /tmp/postremove-proof
RUN test ! -d /usr/share/foo
RUN test ! -d /usr/share/whatever

View File

@ -1,10 +0,0 @@
FROM i386/ubuntu
ARG package
COPY ${package} /tmp/foo.deb
RUN dpkg -i /tmp/foo.deb
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN echo wat >> /etc/foo/whatever.conf
RUN dpkg -r foo
RUN test -f /etc/foo/whatever.conf
RUN test ! -f /usr/local/bin/fake

View File

@ -1,10 +0,0 @@
FROM arm64v8/ubuntu
ARG package
COPY ${package} /tmp/foo.deb
RUN dpkg -i /tmp/foo.deb
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN echo wat >> /etc/foo/whatever.conf
RUN dpkg -r foo
RUN test -f /etc/foo/whatever.conf
RUN test ! -f /usr/local/bin/fake

View File

@ -1,14 +0,0 @@
FROM ubuntu
ARG package
COPY dummy.deb /tmp/dummy.deb
COPY ${package} /tmp/foo.deb
# install dummy package
RUN dpkg -i /tmp/dummy.deb
# make sure foo can't be installed
RUN dpkg -i /tmp/foo.deb 2>&1 | grep "foo breaks dummy"
# make sure foo can be installed if dummy is not installed
RUN dpkg -r dummy
RUN dpkg -i /tmp/foo.deb

View File

@ -1,14 +0,0 @@
FROM ubuntu
ARG package
# the dpkg configuration of the docker
# image filters out changelogs by default
# so we have to remove that rule
RUN rm /etc/dpkg/dpkg.cfg.d/excludes
COPY ${package} /tmp/foo.deb
RUN apt update -y
RUN apt install -y gzip
RUN dpkg -i /tmp/foo.deb
RUN zcat "/usr/share/doc/foo/changelog.gz" | grep "Carlos A Becker <pkg@carlosbecker.com>"
RUN zcat "/usr/share/doc/foo/changelog.gz" | grep "note 1"
RUN zcat "/usr/share/doc/foo/changelog.gz" | grep "note 2"
RUN zcat "/usr/share/doc/foo/changelog.gz" | grep "note 3"

View File

@ -1,30 +0,0 @@
FROM ubuntu
ARG package
COPY ${package} /tmp/foo.deb
RUN dpkg -i /tmp/foo.deb
RUN apt-cache show /tmp/foo.deb | grep "Depends: bash"
RUN apt-cache show /tmp/foo.deb | grep "Suggests: zsh"
RUN apt-cache show /tmp/foo.deb | grep "Recommends: fish"
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN test -d /usr/share/whatever/
RUN test -d /usr/share/whatever/folder
RUN test -f /usr/share/whatever/folder/file1
RUN test -f /usr/share/whatever/folder/file2
RUN test -d /usr/share/whatever/folder/folder2
RUN test -f /usr/share/whatever/folder/folder2/file1
RUN test -f /usr/share/whatever/folder/folder2/file2
RUN test -d /var/log/whatever
RUN test -d /usr/share/foo
RUN test -f /tmp/preinstall-proof
RUN test -f /tmp/postinstall-proof
RUN test ! -f /tmp/preremove-proof
RUN test ! -f /tmp/postremove-proof
RUN echo wat >> /etc/foo/whatever.conf
RUN dpkg -r foo
RUN test -f /etc/foo/whatever.conf
RUN test ! -f /usr/local/bin/fake
RUN test -f /tmp/preremove-proof
RUN test -f /tmp/postremove-proof
RUN test ! -d /var/log/whatever
RUN test ! -d /usr/share/foo

View File

@ -1,10 +1,147 @@
FROM ubuntu
FROM ubuntu AS test_base
ARG package
RUN echo "${package}"
COPY ${package} /tmp/foo.deb
# ---- minimal test ----
FROM test_base AS min
RUN dpkg -i /tmp/foo.deb
# ---- symlink test ----
FROM min AS symlink
RUN ls -l /path/to/symlink | grep "/path/to/symlink -> /etc/foo/whatever.conf"
# ---- simple test ----
FROM min AS simple
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN echo wat >> /etc/foo/whatever.conf
RUN dpkg -r foo
RUN test -f /etc/foo/whatever.conf
RUN test ! -f /usr/local/bin/fake
# ---- no-glob test ----
FROM min AS no-glob
RUN test -d /usr/share/whatever/
RUN test -f /usr/share/whatever/file1
RUN test -f /usr/share/whatever/file2
RUN test -d /usr/share/whatever/folder2
RUN test -f /usr/share/whatever/folder2/file1
RUN test -f /usr/share/whatever/folder2/file2
# ---- complex test ----
FROM min AS complex
RUN apt-cache show /tmp/foo.deb | grep "Depends: bash"
RUN apt-cache show /tmp/foo.deb | grep "Suggests: zsh"
RUN apt-cache show /tmp/foo.deb | grep "Recommends: fish"
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN test -d /usr/share/whatever/
RUN test -d /usr/share/whatever/folder
RUN test -f /usr/share/whatever/folder/file1
RUN test -f /usr/share/whatever/folder/file2
RUN test -d /usr/share/whatever/folder/folder2
RUN test -f /usr/share/whatever/folder/folder2/file1
RUN test -f /usr/share/whatever/folder/folder2/file2
RUN test -d /var/log/whatever
RUN test -d /usr/share/foo
RUN test -f /tmp/preinstall-proof
RUN test -f /tmp/postinstall-proof
RUN test ! -f /tmp/preremove-proof
RUN test ! -f /tmp/postremove-proof
RUN echo wat >> /etc/foo/whatever.conf
RUN dpkg -r foo
RUN test -f /etc/foo/whatever.conf
RUN test ! -f /usr/local/bin/fake
RUN test -f /tmp/preremove-proof
RUN test -f /tmp/postremove-proof
RUN test ! -d /var/log/whatever
RUN test ! -d /usr/share/foo
# ---- signed test ----
FROM test_base AS signed
COPY keys/pubkey.gpg /usr/share/debsig/keyrings/9890904DFB2EC88A/debsig.gpg
RUN apt update -y
RUN apt install -y debsig-verify
COPY deb.policy.pol /etc/debsig/policies/9890904DFB2EC88A/policy.pol
# manually check signature
RUN debsig-verify /tmp/foo.deb | grep "debsig: Verified package from 'Test package' (test)"
# clear dpkg config as it contains 'no-debsig', now every
# package that will be installed must be signed
RUN echo "" > /etc/dpkg/dpkg.cfg
RUN dpkg -i /tmp/foo.deb
# ---- overrides test ----
FROM min AS overrides
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN test ! -f /tmp/preinstall-proof
RUN test -f /tmp/postinstall-proof
RUN test ! -f /tmp/preremove-proof
RUN test ! -f /tmp/postremove-proof
RUN echo wat >> /etc/foo/whatever.conf
RUN dpkg -r foo
RUN test -f /etc/foo/whatever.conf
RUN test ! -f /usr/local/bin/fake
RUN test -f /tmp/preremove-proof
RUN test ! -f /tmp/postremove-proof
# ---- meta test ----
FROM test_base AS meta
RUN apt update && apt install -y /tmp/foo.deb
RUN command -v zsh
RUN command -v fish
# ---- env-var-version test ----
FROM min AS env-var-version
ENV EXPECTVER=" Version: 1.0.0~0.1.b1+git.abcdefgh"
RUN dpkg --info /tmp/foo.deb | grep "Version" > found
RUN export FOUND_VER="$(cat found)" && \
echo "Expected: '${EXPECTVER}' :: Found: '${FOUND_VER}'" && \
test "${FOUND_VER}" = "${EXPECTVER}"
# ---- changelog test ----
FROM test_base AS withchangelog
# the dpkg configuration of the docker
# image filters out changelogs by default
# so we have to remove that rule
RUN rm /etc/dpkg/dpkg.cfg.d/excludes
RUN apt update -y
RUN apt install -y gzip
RUN dpkg -i /tmp/foo.deb
RUN zcat "/usr/share/doc/foo/changelog.gz" | grep "Carlos A Becker <pkg@carlosbecker.com>"
RUN zcat "/usr/share/doc/foo/changelog.gz" | grep "note 1"
RUN zcat "/usr/share/doc/foo/changelog.gz" | grep "note 2"
RUN zcat "/usr/share/doc/foo/changelog.gz" | grep "note 3"
# ---- rules test ----
FROM min AS rules
RUN dpkg -r foo
# ---- triggers test ----
FROM min as triggers
# simulate another package that activates the trigger
RUN dpkg-trigger --by-package foo manual-trigger
RUN dpkg --triggers-only foo
RUN test -f /tmp/trigger-proof
# ---- breaks test ----
FROM test_base AS breaks
COPY dummy.deb /tmp/dummy.deb
# install dummy package
RUN dpkg -i /tmp/dummy.deb
# make sure foo can't be installed
RUN dpkg -i /tmp/foo.deb 2>&1 | grep "foo breaks dummy"
# make sure foo can be installed if dummy is not installed
RUN dpkg -r dummy
RUN dpkg -i /tmp/foo.deb

View File

@ -1,8 +0,0 @@
FROM ubuntu
ARG package
COPY ${package} /tmp/foo.deb
ENV EXPECTVER=" Version: 1.0.0~0.1.b1+git.abcdefgh"
RUN dpkg --info /tmp/foo.deb | grep "Version" > found
RUN export FOUND_VER="$(cat found)" && \
echo "Expected: '${EXPECTVER}' :: Found: '${FOUND_VER}'" && \
test "${FOUND_VER}" = "${EXPECTVER}"

View File

@ -1,6 +0,0 @@
FROM ubuntu
ARG package
COPY ${package} /tmp/foo.deb
RUN apt update && apt install -y /tmp/foo.deb
RUN command -v zsh
RUN command -v fish

View File

@ -1,4 +0,0 @@
FROM ubuntu
ARG package
COPY ${package} /tmp/foo.deb
RUN dpkg -i /tmp/foo.deb

View File

@ -1,16 +0,0 @@
FROM ubuntu
ARG package
COPY ${package} /tmp/foo.deb
RUN dpkg -i /tmp/foo.deb
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN test ! -f /tmp/preinstall-proof
RUN test -f /tmp/postinstall-proof
RUN test ! -f /tmp/preremove-proof
RUN test ! -f /tmp/postremove-proof
RUN echo wat >> /etc/foo/whatever.conf
RUN dpkg -r foo
RUN test -f /etc/foo/whatever.conf
RUN test ! -f /usr/local/bin/fake
RUN test -f /tmp/preremove-proof
RUN test ! -f /tmp/postremove-proof

11
testdata/acceptance/deb.policy.pol vendored Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0"?>
<!DOCTYPE Policy SYSTEM "https://www.debian.org/debsig/1.0/policy.dtd">
<Policy xmlns="https://www.debian.org/debsig/1.0/">
<Origin Name="test" id="9890904DFB2EC88A" Description="Test package"/>
<Selection>
<Required Type="origin" File="debsig.gpg" id="9890904DFB2EC88A"/>
</Selection>
<Verification MinOptional="0">
<Required Type="origin" File="debsig.gpg" id="9890904DFB2EC88A"/>
</Verification>
</Policy>

View File

@ -1,10 +0,0 @@
FROM ppc64le/ubuntu
ARG package
COPY ${package} /tmp/foo.deb
RUN dpkg -i /tmp/foo.deb
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN echo wat >> /etc/foo/whatever.conf
RUN dpkg -r foo
RUN test -f /etc/foo/whatever.conf
RUN test ! -f /usr/local/bin/fake

View File

@ -1,5 +1,5 @@
name: "foo"
arch: "amd64"
arch: "${BUILD_ARCH}"
platform: "linux"
version: "v1.2.3"
maintainer: "Foo Bar"

View File

@ -1,32 +0,0 @@
FROM ubuntu
ARG package
COPY keys/pubkey.gpg /usr/share/debsig/keyrings/9890904DFB2EC88A/debsig.gpg
COPY ${package} /tmp/foo.deb
RUN apt update -y
RUN apt install -y debsig-verify
RUN mkdir -p /etc/debsig/policies/9890904DFB2EC88A
RUN echo '<?xml version="1.0"?>\n\
<!DOCTYPE Policy SYSTEM "https://www.debian.org/debsig/1.0/policy.dtd">\n\
<Policy xmlns="https://www.debian.org/debsig/1.0/">\n\
\n\
<Origin Name="test" id="9890904DFB2EC88A" Description="Test package"/>\n\
\n\
<Selection>\n\
<Required Type="origin" File="debsig.gpg" id="9890904DFB2EC88A"/>\n\
</Selection>\n\
\n\
<Verification MinOptional="0">\n\
<Required Type="origin" File="debsig.gpg" id="9890904DFB2EC88A"/>\n\
</Verification>\n\
</Policy>\n\
\n' >> /etc/debsig/policies/9890904DFB2EC88A/policy.pol
# manually check signature
RUN debsig-verify /tmp/foo.deb
RUN debsig-verify /tmp/foo.deb | grep "debsig: Verified package from 'Test package' (test)"
# clear dpkg config as it contains 'no-debsig', now every
# package that will be installed must be signed
RUN echo "" > /etc/dpkg/dpkg.cfg
RUN dpkg -i /tmp/foo.deb

View File

@ -1,5 +0,0 @@
FROM ubuntu
ARG package
COPY ${package} /tmp/foo.deb
RUN dpkg -i /tmp/foo.deb
RUN ls -l /path/to/symlink | grep "/path/to/symlink -> /etc/foo/whatever.conf"

View File

@ -1,9 +0,0 @@
FROM ubuntu
ARG package
COPY ${package} /tmp/foo.deb
RUN dpkg -i /tmp/foo.deb
# simulate another package that activates the trigger
RUN dpkg-trigger --by-package foo manual-trigger
RUN dpkg --triggers-only foo
RUN test -f /tmp/trigger-proof

View File

@ -1,5 +1,5 @@
name: "foo"
arch: "amd64"
arch: "${BUILD_ARCH}"
platform: "linux"
version: "v1.2.3-beta"
maintainer: "Foo Bar"

View File

@ -0,0 +1 @@
file1

View File

@ -0,0 +1 @@
file2

View File

@ -0,0 +1 @@
folder2-file1

View File

@ -0,0 +1 @@
folder2-file2

View File

@ -1,11 +0,0 @@
FROM fedora
ARG package
COPY ${package} /tmp/foo.rpm
RUN test "gzip" = "$(rpm -qp --qf '%{PAYLOADCOMPRESSOR}' /tmp/foo.rpm)"
RUN rpm -ivh /tmp/foo.rpm
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN echo wat >> /etc/foo/whatever.conf
RUN rpm -e foo
RUN test -f /etc/foo/whatever.conf.rpmsave
RUN test ! -f /usr/local/bin/fake

View File

@ -1,11 +0,0 @@
FROM fedora
ARG package
COPY ${package} /tmp/foo.rpm
RUN test "lzma" = "$(rpm -qp --qf '%{PAYLOADCOMPRESSOR}' /tmp/foo.rpm)"
RUN rpm -ivh /tmp/foo.rpm
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN echo wat >> /etc/foo/whatever.conf
RUN rpm -e foo
RUN test -f /etc/foo/whatever.conf.rpmsave
RUN test ! -f /usr/local/bin/fake

View File

@ -1,10 +0,0 @@
FROM fedora
ARG package
COPY ${package} /tmp/foo.rpm
RUN rpm -ivh /tmp/foo.rpm
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN echo wat >> /etc/foo/whatever.conf
RUN rpm -e foo
RUN test -f /etc/foo/whatever.conf.rpmsave
RUN test ! -f /usr/local/bin/fake

View File

@ -1,26 +0,0 @@
FROM i386/centos
ARG package
COPY ${package} /tmp/foo.rpm
RUN rpm -ivh /tmp/foo.rpm
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN test -d /usr/share/whatever/folder
RUN test -f /usr/share/whatever/folder/file1
RUN test -f /usr/share/whatever/folder/file2
RUN test -d /usr/share/whatever/folder/folder2
RUN test -f /usr/share/whatever/folder/folder2/file1
RUN test -f /usr/share/whatever/folder/folder2/file2
RUN test -d /var/log/whatever
RUN test -d /usr/share/foo
RUN test -f /tmp/preinstall-proof
RUN test -f /tmp/postinstall-proof
RUN test ! -f /tmp/preremove-proof
RUN test ! -f /tmp/postremove-proof
RUN echo wat >> /etc/foo/whatever.conf
RUN rpm -e foo
RUN test -f /etc/foo/whatever.conf.rpmsave
RUN test ! -f /usr/local/bin/fake
RUN test -f /tmp/preremove-proof
RUN test -f /tmp/postremove-proof
RUN test ! -d /var/log/whatever
RUN test ! -d /usr/share/foo

View File

@ -1,10 +0,0 @@
FROM i386/centos
ARG package
COPY ${package} /tmp/foo.rpm
RUN rpm -ivh /tmp/foo.rpm
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN echo wat >> /etc/foo/whatever.conf
RUN rpm -e foo
RUN test -f /etc/foo/whatever.conf.rpmsave
RUN test ! -f /usr/local/bin/fake

View File

@ -1,10 +0,0 @@
FROM arm64v8/centos
ARG package
COPY ${package} /tmp/foo.rpm
RUN rpm -ivh /tmp/foo.rpm
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN echo wat >> /etc/foo/whatever.conf
RUN rpm -e foo
RUN test -f /etc/foo/whatever.conf.rpmsave
RUN test ! -f /usr/local/bin/fake

View File

@ -1,12 +0,0 @@
FROM fedora
ARG package
COPY ${package} /tmp/foo.rpm
RUN rpm -ivh /tmp/foo.rpm
RUN rpm -qp /tmp/foo.rpm --changelog | grep "Carlos A Becker <pkg@carlosbecker.com>"
RUN rpm -qp /tmp/foo.rpm --changelog | grep -E "^- note 1$"
RUN rpm -qp /tmp/foo.rpm --changelog | grep -E "^- note 2$"
RUN rpm -qp /tmp/foo.rpm --changelog | grep -E "^- note 3$"
RUN rpm -q foo --changelog | grep "Carlos A Becker <pkg@carlosbecker.com>"
RUN rpm -q foo --changelog | grep -E "^- note 1$"
RUN rpm -q foo --changelog | grep -E "^- note 2$"
RUN rpm -q foo --changelog | grep -E "^- note 3$"

View File

@ -1,29 +0,0 @@
FROM fedora
ARG package
COPY ${package} /tmp/foo.rpm
RUN test "$(rpm -qp --recommends /tmp/foo.rpm)" = "fish"
RUN test "$(rpm -qp --suggests /tmp/foo.rpm)" = "zsh"
RUN test "$(rpm -qp --requires /tmp/foo.rpm)" = "bash"
RUN rpm -ivh /tmp/foo.rpm
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN test -d /usr/share/whatever/folder
RUN test -f /usr/share/whatever/folder/file1
RUN test -f /usr/share/whatever/folder/file2
RUN test -d /usr/share/whatever/folder/folder2
RUN test -f /usr/share/whatever/folder/folder2/file1
RUN test -f /usr/share/whatever/folder/folder2/file2
RUN test -d /var/log/whatever
RUN test -d /usr/share/foo
RUN test -f /tmp/preinstall-proof
RUN test -f /tmp/postinstall-proof
RUN test ! -f /tmp/preremove-proof
RUN test ! -f /tmp/postremove-proof
RUN echo wat >> /etc/foo/whatever.conf
RUN rpm -e foo
RUN test -f /etc/foo/whatever.conf.rpmsave
RUN test ! -f /usr/local/bin/fake
RUN test -f /tmp/preremove-proof
RUN test -f /tmp/postremove-proof
RUN test ! -d /var/log/whatever
RUN test ! -d /usr/share/foo

View File

@ -1,19 +0,0 @@
FROM fedora
ARG package
COPY ${package} /tmp/new_foo.rpm
COPY tmp/noreplace_old_rpm.rpm /tmp/old_foo.rpm
RUN rpm -ivh /tmp/old_foo.rpm
RUN echo modified > /etc/regular.conf
RUN echo modified > /etc/noreplace.conf
RUN rpm -ivh /tmp/new_foo.rpm --upgrade
RUN cat /etc/regular.conf | grep foo=baz
RUN test -f /etc/regular.conf.rpmsave
RUN cat /etc/regular.conf.rpmsave | grep modified
RUN cat /etc/noreplace.conf | grep modified
RUN test -f /etc/noreplace.conf.rpmnew
RUN cat /etc/noreplace.conf.rpmnew | grep foo=baz

View File

@ -1,10 +1,175 @@
FROM fedora
FROM fedora AS test_base
ARG package
RUN echo "${package}"
COPY ${package} /tmp/foo.rpm
# ---- minimal test ----
FROM test_base AS min
RUN rpm -ivh /tmp/foo.rpm
# ---- symlink test ----
FROM min AS symlink
RUN ls -l /path/to/symlink | grep "/path/to/symlink -> /etc/foo/whatever.conf"
# ---- simple test ----
FROM min AS simple
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN echo wat >> /etc/foo/whatever.conf
RUN rpm -e foo
RUN test -f /etc/foo/whatever.conf.rpmsave
RUN test ! -f /usr/local/bin/fake
# ---- no-glob test ----
FROM min AS no-glob
RUN test -d /usr/share/whatever/
RUN test -f /usr/share/whatever/file1
RUN test -f /usr/share/whatever/file2
RUN test -d /usr/share/whatever/folder2
RUN test -f /usr/share/whatever/folder2/file1
RUN test -f /usr/share/whatever/folder2/file2
# ---- complex test ----
FROM min AS complex
RUN test "$(rpm -qp --recommends /tmp/foo.rpm)" = "fish"
RUN test "$(rpm -qp --suggests /tmp/foo.rpm)" = "zsh"
RUN test "$(rpm -qp --requires /tmp/foo.rpm)" = "bash"
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN test -d /usr/share/whatever/folder
RUN test -f /usr/share/whatever/folder/file1
RUN test -f /usr/share/whatever/folder/file2
RUN test -d /usr/share/whatever/folder/folder2
RUN test -f /usr/share/whatever/folder/folder2/file1
RUN test -f /usr/share/whatever/folder/folder2/file2
RUN test -d /var/log/whatever
RUN test -d /usr/share/foo
RUN test -f /tmp/preinstall-proof
RUN test -f /tmp/postinstall-proof
RUN test ! -f /tmp/preremove-proof
RUN test ! -f /tmp/postremove-proof
RUN echo wat >> /etc/foo/whatever.conf
RUN rpm -e foo
RUN test -f /etc/foo/whatever.conf.rpmsave
RUN test ! -f /usr/local/bin/fake
RUN test -f /tmp/preremove-proof
RUN test -f /tmp/postremove-proof
RUN test ! -d /var/log/whatever
RUN test ! -d /usr/share/foo
# ---- signed test ----
FROM test_base AS signed
COPY keys/pubkey.asc /tmp/pubkey.asc
RUN rpm --import /tmp/pubkey.asc
RUN rpm -q gpg-pubkey --qf '%{NAME}-%{VERSION}-%{RELEASE}\t%{SUMMARY}\n'
RUN rpm -K /tmp/foo.rpm
RUN rpm -K /tmp/foo.rpm | grep -E "(?:pgp|digests signatures) OK"
RUN rpm -vK /tmp/foo.rpm
RUN rpm -vK /tmp/foo.rpm | grep "RSA/SHA256 Signature, key ID 15bd80b3: OK"
# Test with a repo
RUN yum install -y createrepo yum-utils
RUN rm -rf /etc/yum.repos.d/*.repo
COPY keys/test.rpm.repo /etc/yum.repos.d/test.rpm.repo
RUN createrepo /tmp
RUN yum install -y foo
# ---- overrides test ----
FROM min AS overrides
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN test -d /usr/share/whatever/folder
RUN test -f /usr/share/whatever/folder/file1
RUN test -f /usr/share/whatever/folder/file2
RUN test -d /usr/share/whatever/folder/folder2
RUN test -f /usr/share/whatever/folder/folder2/file1
RUN test -f /usr/share/whatever/folder/folder2/file2
RUN test -f /tmp/preinstall-proof
RUN test ! -f /tmp/postinstall-proof
RUN test ! -f /tmp/preremove-proof
RUN test ! -f /tmp/postremove-proof
RUN echo wat >> /etc/foo/whatever.conf
RUN rpm -e foo
RUN test -f /etc/foo/whatever.conf.rpmsave
RUN test ! -f /usr/local/bin/fake
RUN test ! -f /tmp/preremove-proof
RUN test -f /tmp/postremove-proof
# ---- meta test ----
FROM test_base AS meta
RUN dnf install -y /tmp/foo.rpm
RUN command -v zsh
RUN command -v fish
# ---- env-var-version test ----
FROM min AS env-var-version
ENV EXPECTVER="Version : 1.0.0~0.1.b1+git.abcdefgh" \
EXPECTREL="Release : 1"
RUN rpm -qpi /tmp/foo.rpm | sed -e 's/ \+/ /g' | grep "Version" > found.ver
RUN rpm -qpi /tmp/foo.rpm | sed -e 's/ \+/ /g' | grep "Release" > found.rel
RUN export FOUND_VER="$(cat found.ver)" && \
echo "Expected: ${EXPECTVER}' :: Found: '${FOUND_VER}'" && \
test "${FOUND_VER}" = "${EXPECTVER}"
RUN export FOUND_REL="$(cat found.rel)" && \
echo "Expected: '${EXPECTREL}' :: Found: '${FOUND_REL}'" && \
test "${FOUND_REL}" = "${EXPECTREL}"
# ---- changelog test ----
FROM min AS withchangelog
RUN rpm -qp /tmp/foo.rpm --changelog | grep "Carlos A Becker <pkg@carlosbecker.com>"
RUN rpm -qp /tmp/foo.rpm --changelog | grep -E "^- note 1$"
RUN rpm -qp /tmp/foo.rpm --changelog | grep -E "^- note 2$"
RUN rpm -qp /tmp/foo.rpm --changelog | grep -E "^- note 3$"
RUN rpm -q foo --changelog | grep "Carlos A Becker <pkg@carlosbecker.com>"
RUN rpm -q foo --changelog | grep -E "^- note 1$"
RUN rpm -q foo --changelog | grep -E "^- note 2$"
RUN rpm -q foo --changelog | grep -E "^- note 3$"
# ---- compression test ----
FROM min AS compression
ARG compression
RUN test "${compression}" = "$(rpm -qp --qf '%{PAYLOADCOMPRESSOR}' /tmp/foo.rpm)"
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN echo wat >> /etc/foo/whatever.conf
RUN rpm -e foo
RUN test -f /etc/foo/whatever.conf.rpmsave
RUN test ! -f /usr/local/bin/fake
# ---- config-noreplace test ----
FROM test_base AS config-noreplace
COPY tmp/noreplace_old_rpm.rpm /tmp/old_foo.rpm
RUN rpm -ivh /tmp/old_foo.rpm
RUN echo modified > /etc/regular.conf
RUN echo modified > /etc/noreplace.conf
RUN rpm -ivh /tmp/foo.rpm --upgrade
RUN cat /etc/regular.conf | grep foo=baz
RUN test -f /etc/regular.conf.rpmsave
RUN cat /etc/regular.conf.rpmsave | grep modified
RUN cat /etc/noreplace.conf | grep modified
RUN test -f /etc/noreplace.conf.rpmnew
RUN cat /etc/noreplace.conf.rpmnew | grep foo=baz
# ---- release test ----
FROM min AS release
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN echo wat >> /etc/foo/whatever.conf
RUN rpm -e foo
RUN test -f /etc/foo/whatever.conf.rpmsave
RUN test ! -f /usr/local/bin/fake

View File

@ -1,13 +0,0 @@
FROM fedora
ARG package
COPY ${package} /tmp/foo.rpm
ENV EXPECTVER="Version : 1.0.0~0.1.b1+git.abcdefgh" \
EXPECTREL="Release : 1"
RUN rpm -qpi /tmp/foo.rpm | sed -e 's/ \+/ /g' | grep "Version" > found.ver
RUN rpm -qpi /tmp/foo.rpm | sed -e 's/ \+/ /g' | grep "Release" > found.rel
RUN export FOUND_VER="$(cat found.ver)" && \
echo "Expected: ${EXPECTVER}' :: Found: '${FOUND_VER}'" && \
test "${FOUND_VER}" = "${EXPECTVER}"
RUN export FOUND_REL="$(cat found.rel)" && \
echo "Expected: '${EXPECTREL}' :: Found: '${FOUND_REL}'" && \
test "${FOUND_REL}" = "${EXPECTREL}"

View File

@ -1,5 +1,5 @@
name: "foo"
arch: "amd64"
arch: "${BUILD_ARCH}"
platform: "linux"
version: "v1.2.3"
maintainer: "Foo Bar"

View File

@ -1,5 +1,5 @@
name: "foo"
arch: "amd64"
arch: "${BUILD_ARCH}"
platform: "linux"
version: "v1.2.3"
maintainer: "Foo Bar"

View File

@ -1,6 +0,0 @@
FROM fedora
ARG package
COPY ${package} /tmp/foo.rpm
RUN dnf install -y /tmp/foo.rpm
RUN command -v zsh
RUN command -v fish

View File

@ -1,6 +0,0 @@
FROM fedora
ARG package
COPY ${package} /tmp/foo.rpm
RUN rpm -ivh /tmp/foo.rpm
RUN rpm -e foo
RUN rpm -qvl /tmp/foo.rpm | grep -E "root\s+root"

View File

@ -1,22 +0,0 @@
FROM fedora
ARG package
COPY ${package} /tmp/foo.rpm
RUN rpm -ivh /tmp/foo.rpm
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN test -d /usr/share/whatever/folder
RUN test -f /usr/share/whatever/folder/file1
RUN test -f /usr/share/whatever/folder/file2
RUN test -d /usr/share/whatever/folder/folder2
RUN test -f /usr/share/whatever/folder/folder2/file1
RUN test -f /usr/share/whatever/folder/folder2/file2
RUN test -f /tmp/preinstall-proof
RUN test ! -f /tmp/postinstall-proof
RUN test ! -f /tmp/preremove-proof
RUN test ! -f /tmp/postremove-proof
RUN echo wat >> /etc/foo/whatever.conf
RUN rpm -e foo
RUN test -f /etc/foo/whatever.conf.rpmsave
RUN test ! -f /usr/local/bin/fake
RUN test ! -f /tmp/preremove-proof
RUN test -f /tmp/postremove-proof

View File

@ -1,10 +0,0 @@
FROM ppc64le/centos
ARG package
COPY ${package} /tmp/foo.rpm
RUN rpm -ivh /tmp/foo.rpm
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN echo wat >> /etc/foo/whatever.conf
RUN rpm -e foo
RUN test -f /etc/foo/whatever.conf.rpmsave
RUN test ! -f /usr/local/bin/fake

View File

@ -1,5 +1,5 @@
name: "foo"
arch: "amd64"
arch: "${BUILD_ARCH}"
platform: "linux"
version: "v1.2.3"
maintainer: "Foo Bar"

View File

@ -1,18 +0,0 @@
FROM centos:7
ARG package
COPY keys/pubkey.asc /tmp/pubkey.asc
COPY ${package} /tmp/foo.rpm
RUN rpm --import /tmp/pubkey.asc
RUN rpm -q gpg-pubkey --qf '%{NAME}-%{VERSION}-%{RELEASE}\t%{SUMMARY}\n'
RUN rpm -K /tmp/foo.rpm
RUN rpm -K /tmp/foo.rpm | grep "pgp OK"
RUN rpm -vK /tmp/foo.rpm
RUN rpm -vK /tmp/foo.rpm | grep "RSA/SHA256 Signature, key ID 15bd80b3: OK"
# Test with a repo
RUN yum install -y createrepo yum-utils
RUN rm -rf /etc/yum.repos.d/*.repo
COPY keys/test.rpm.repo /etc/yum.repos.d/test.rpm.repo
RUN createrepo /tmp
RUN yum install -y foo

View File

@ -1,5 +0,0 @@
FROM fedora
ARG package
COPY ${package} /tmp/foo.rpm
RUN rpm -ivh /tmp/foo.rpm
RUN ls -l /path/to/symlink | grep "/path/to/symlink -> /etc/foo/whatever.conf"

View File

@ -1,5 +1,5 @@
name: "foo"
arch: "amd64"
arch: "${BUILD_ARCH}"
platform: "linux"
version: "v1.2.3"
maintainer: "Foo Bar"

View File

@ -1,5 +0,0 @@
FROM ubuntu
ARG package
COPY ${package} /tmp/foo.deb
RUN dpkg -i /tmp/foo.deb
RUN dpkg -r foo

View File

@ -1,17 +0,0 @@
name: "foo"
arch: "386"
platform: "linux"
version: "v1.2.3"
maintainer: "Foo Bar"
description: |
Foo bar
Multiple lines
vendor: "foobar"
homepage: "https://foobar.org"
license: "MIT"
contents:
- src: ./testdata/fake
dst: /usr/local/bin/fake
- src: ./testdata/whatever.conf
dst: /etc/foo/whatever.conf
type: config

View File

@ -1,17 +0,0 @@
name: "foo"
arch: "arm64"
platform: "linux"
version: "v1.2.3"
maintainer: "Foo Bar"
description: |
Foo bar
Multiple lines
vendor: "foobar"
homepage: "https://foobar.org"
license: "MIT"
contents:
- src: ./testdata/fake
dst: /usr/local/bin/fake
- src: ./testdata/whatever.conf
dst: /etc/foo/whatever.conf
type: config

View File

@ -1,17 +0,0 @@
name: "foo"
arch: "ppc64le"
platform: "linux"
version: "v1.2.3"
maintainer: "Foo Bar"
description: |
Foo bar
Multiple lines
vendor: "foobar"
homepage: "https://foobar.org"
license: "MIT"
contents:
- src: ./testdata/fake
dst: /usr/local/bin/fake
- src: ./testdata/whatever.conf
dst: /etc/foo/whatever.conf
type: config

View File

@ -1,11 +0,0 @@
FROM fedora
ARG package
COPY ${package} /tmp/foo.rpm
RUN test "xz" = "$(rpm -qp --qf '%{PAYLOADCOMPRESSOR}' /tmp/foo.rpm)"
RUN rpm -ivh /tmp/foo.rpm
RUN test -e /usr/local/bin/fake
RUN test -f /etc/foo/whatever.conf
RUN echo wat >> /etc/foo/whatever.conf
RUN rpm -e foo
RUN test -f /etc/foo/whatever.conf.rpmsave
RUN test ! -f /usr/local/bin/fake

8
testdata/contents_directory.yaml vendored Normal file
View File

@ -0,0 +1,8 @@
# Configuration file used to unit test enhanced file map
name: "foo"
arch: "amd64"
version: "v1.2.3"
disable_globbing: true
contents:
- src: "testdata/globtest"
dst: "/etc/foo"