container credentials (#868)
* Chore: add a snapshot target * Update: support credentials for private containers Resolves: #788 * fix: rework container credentials Signed-off-by: hackercat <me@hackerc.at> * fix: check if Credentials are not nil * fix: return on missing credentials key Co-authored-by: hackercat <me@hackerc.at> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
parent
e793d03f4b
commit
5bdb9ed0fd
4 changed files with 88 additions and 11 deletions
7
Makefile
7
Makefile
|
@ -104,3 +104,10 @@ ifneq ($(shell git status -s),)
|
||||||
endif
|
endif
|
||||||
git tag -a -m "releasing v$(NEW_VERSION)" v$(NEW_VERSION)
|
git tag -a -m "releasing v$(NEW_VERSION)" v$(NEW_VERSION)
|
||||||
git push origin v$(NEW_VERSION)
|
git push origin v$(NEW_VERSION)
|
||||||
|
|
||||||
|
.PHONY: snapshot
|
||||||
|
snapshot:
|
||||||
|
goreleaser build \
|
||||||
|
--rm-dist \
|
||||||
|
--single-target \
|
||||||
|
--snapshot
|
||||||
|
|
|
@ -300,6 +300,7 @@ type ContainerSpec struct {
|
||||||
Ports []string `yaml:"ports"`
|
Ports []string `yaml:"ports"`
|
||||||
Volumes []string `yaml:"volumes"`
|
Volumes []string `yaml:"volumes"`
|
||||||
Options string `yaml:"options"`
|
Options string `yaml:"options"`
|
||||||
|
Credentials map[string]string `yaml:"credentials"`
|
||||||
Entrypoint string
|
Entrypoint string
|
||||||
Args string
|
Args string
|
||||||
Name string
|
Name string
|
||||||
|
|
|
@ -99,6 +99,36 @@ jobs:
|
||||||
assert.Contains(t, workflow.Jobs["test2"].Container().Env["foo"], "bar")
|
assert.Contains(t, workflow.Jobs["test2"].Container().Env["foo"], "bar")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReadWorkflow_ObjectContainer(t *testing.T) {
|
||||||
|
yaml := `
|
||||||
|
name: local-action-docker-url
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
container:
|
||||||
|
image: r.example.org/something:latest
|
||||||
|
credentials:
|
||||||
|
username: registry-username
|
||||||
|
password: registry-password
|
||||||
|
env:
|
||||||
|
HOME: /home/user
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: ./actions/docker-url
|
||||||
|
`
|
||||||
|
|
||||||
|
workflow, err := ReadWorkflow(strings.NewReader(yaml))
|
||||||
|
assert.NoError(t, err, "read workflow should succeed")
|
||||||
|
assert.Len(t, workflow.Jobs, 1)
|
||||||
|
|
||||||
|
container := workflow.GetJob("test").Container()
|
||||||
|
|
||||||
|
assert.Contains(t, container.Image, "r.example.org/something:latest")
|
||||||
|
assert.Contains(t, container.Env["HOME"], "/home/user")
|
||||||
|
assert.Contains(t, container.Credentials["username"], "registry-username")
|
||||||
|
assert.Contains(t, container.Credentials["password"], "registry-password")
|
||||||
|
}
|
||||||
|
|
||||||
func TestReadWorkflow_StepsTypes(t *testing.T) {
|
func TestReadWorkflow_StepsTypes(t *testing.T) {
|
||||||
yaml := `
|
yaml := `
|
||||||
name: invalid step definition
|
name: invalid step definition
|
||||||
|
|
|
@ -153,6 +153,11 @@ func (rc *RunContext) startJobContainer() common.Executor {
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
username, password, err := rc.handleCredentials()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to handle credentials: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
common.Logger(ctx).Infof("\U0001f680 Start image=%s", image)
|
common.Logger(ctx).Infof("\U0001f680 Start image=%s", image)
|
||||||
name := rc.jobContainerName()
|
name := rc.jobContainerName()
|
||||||
|
|
||||||
|
@ -169,8 +174,8 @@ func (rc *RunContext) startJobContainer() common.Executor {
|
||||||
Entrypoint: []string{"/usr/bin/tail", "-f", "/dev/null"},
|
Entrypoint: []string{"/usr/bin/tail", "-f", "/dev/null"},
|
||||||
WorkingDir: rc.Config.ContainerWorkdir(),
|
WorkingDir: rc.Config.ContainerWorkdir(),
|
||||||
Image: image,
|
Image: image,
|
||||||
Username: rc.Config.Secrets["DOCKER_USERNAME"],
|
Username: username,
|
||||||
Password: rc.Config.Secrets["DOCKER_PASSWORD"],
|
Password: password,
|
||||||
Name: name,
|
Name: name,
|
||||||
Env: envList,
|
Env: envList,
|
||||||
Mounts: mounts,
|
Mounts: mounts,
|
||||||
|
@ -836,3 +841,37 @@ func (rc *RunContext) localCheckoutPath() (string, bool) {
|
||||||
}
|
}
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rc *RunContext) handleCredentials() (username, password string, err error) {
|
||||||
|
// TODO: remove below 2 lines when we can release act with breaking changes
|
||||||
|
username = rc.Config.Secrets["DOCKER_USERNAME"]
|
||||||
|
password = rc.Config.Secrets["DOCKER_PASSWORD"]
|
||||||
|
|
||||||
|
container := rc.Run.Job().Container()
|
||||||
|
if container == nil || container.Credentials == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if container.Credentials != nil && len(container.Credentials) != 2 {
|
||||||
|
err = fmt.Errorf("invalid property count for key 'credentials:'")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ee := rc.NewExpressionEvaluator()
|
||||||
|
var ok bool
|
||||||
|
if username, ok = ee.InterpolateWithStringCheck(container.Credentials["username"]); !ok {
|
||||||
|
err = fmt.Errorf("failed to interpolate container.credentials.username")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if password, ok = ee.InterpolateWithStringCheck(container.Credentials["password"]); !ok {
|
||||||
|
err = fmt.Errorf("failed to interpolate container.credentials.password")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if container.Credentials["username"] == "" || container.Credentials["password"] == "" {
|
||||||
|
err = fmt.Errorf("container.credentials cannot be empty")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return username, password, err
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue