Skip to content
This repository was archived by the owner on Jun 22, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
316b48b
Adding github and login args and command
zappy-shu Feb 20, 2020
d062807
Adding build opts and default tags/labels
zappy-shu Feb 21, 2020
2f380ad
Removing run ID and number
zappy-shu Feb 21, 2020
421f37e
Adding build command
zappy-shu Feb 21, 2020
5605e2c
Add ability to override both dockerfile and path
zappy-shu Feb 24, 2020
0f77e60
Add initial e2e framework
zappy-shu Feb 24, 2020
d9614cd
Create registry from Dockerfile for e2e
zappy-shu Feb 24, 2020
a090946
Add poll to e2e login
zappy-shu Feb 24, 2020
b39a5bf
Add e2e tests for build
zappy-shu Feb 24, 2020
b61c5d7
Extract tags from build options
zappy-shu Feb 24, 2020
7c1edfc
Extract server from build and login options
zappy-shu Feb 24, 2020
212300f
Add push command
zappy-shu Feb 25, 2020
f6482be
Build/lint/unit-test in one docker build
zappy-shu Feb 25, 2020
cf7a3c0
Add build-push command and tests
zappy-shu Feb 25, 2020
8754d5a
try using buildkit
zappy-shu Feb 25, 2020
c6df8c6
Add short-sha to tags
zappy-shu Feb 25, 2020
17373ac
Updating readme with env vars
zappy-shu Feb 26, 2020
09a935f
Refactor command running
zappy-shu Feb 26, 2020
8c0a723
Add push filter
zappy-shu Feb 27, 2020
4cc816e
Split tags for sha and ref
zappy-shu Mar 3, 2020
5c92bfd
Switching from urfave/cli to cobra
zappy-shu Mar 3, 2020
cb5ad12
Error is username or password set but not both
zappy-shu Mar 4, 2020
6867dc1
Refactoring nits for PR
zappy-shu Mar 4, 2020
f929a47
Use hashicorp/go-multierror
zappy-shu Mar 4, 2020
78d3747
Remove unrequired Getwd() from e2e tests
zappy-shu Mar 4, 2020
ba8eb48
Use cmd.Env to set env vars in e2e tests
zappy-shu Mar 4, 2020
791388d
Update doc for INPUT_TARGET to match cli help
zappy-shu Mar 4, 2020
e856f73
Add git labels description in readme
zappy-shu Mar 4, 2020
8049084
Rename server input to registry
zappy-shu Mar 4, 2020
66d44b6
Return err when boolean inputs invalid
zappy-shu Mar 4, 2020
e93e32e
Only replace / when tagging with ref
zappy-shu Mar 4, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,14 @@ jobs:
- name: Checkout
uses: actions/checkout@v2

- name: Print env
run: env

- name: Read event json
run: cat $GITHUB_EVENT_PATH

- name: Build
run: make -f docker.Makefile
run: DOCKER_BUILDKIT=1 make -f docker.Makefile build

- name: E2E
run: DOCKER_BUILDKIT=1 make -f docker.Makefile test-e2e
28 changes: 23 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
ARG GO_VERSION=1.13.7
ARG GOLANGCI_LINT_VERSION=v1.23.6
ARG ALPINE_VERSION=3.11.3

ARG DND_VERSION=19.03


# Builds the github-actions binary, checks linting, and runs unit level tests
FROM golang:${GO_VERSION} AS builder

RUN curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin ${GOLANGCI_LINT_VERSION}

ARG MAKE_TARGET=all
ARG MAKE_TARGET=default
ENV CGO_ENABLED=0
WORKDIR /src

Expand All @@ -17,13 +17,31 @@ COPY . .
RUN make ${MAKE_TARGET}


# Used to run e2e tests for github-actions
# This image must be run as a container to run the tests
FROM golang:${GO_VERSION} AS e2e
ARG CLI_CHANNEL=stable
ARG CLI_VERSION=19.03.5

RUN apt-get install -y -q --no-install-recommends coreutils util-linux

ENV CGO_ENABLED=0
ENV GITHUB_ACTIONS_BINARY=/github-actions
WORKDIR /tests

RUN curl -fL https://download.docker.com/linux/static/${CLI_CHANNEL}/x86_64/docker-${CLI_VERSION}.tgz | tar xzO docker/docker > /usr/bin/docker && chmod +x /usr/bin/docker

COPY . .
COPY --from=builder /src/bin/github-actions /github-actions


# Used to extract the github-actions binary
FROM scratch AS cli
COPY --from=builder /src/bin/github-actions github-actions



FROM alpine:${ALPINE_VERSION}
# The github-actions image that is used by published docker github actions
FROM docker:${DND_VERSION}

COPY --from=builder /src/bin/github-actions /github-actions

Expand Down
14 changes: 11 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
all: build lint test
default: build lint test-unit

all: default test-e2e

build:
@$(call mkdir,bin)
Expand All @@ -7,5 +9,11 @@ build:
lint:
golangci-lint run --config golangci.yml ./...

test:
go test ./...
test: test-unit test-e2e

test-unit:
go test ./cmd/... ./internal/...

test-e2e: build
docker build --file ./e2e/Dockerfile.registry -t github-actions-registry ./e2e
go test ./e2e/...
135 changes: 131 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,143 @@
# github-actions
The core code base for Docker's GitHub Actions (https://github.com/features/actions). This code is used to build the docker/github-actions image that provides the functionality used by the published Docker GitHub Actions
The core code base for Docker's GitHub Actions (https://github.com/features/actions). This code is used to build the docker/github-actions image that provides the functionality used by the published Docker GitHub Actions.

`github-actions` runs a command line tool that shells out to docker to perform the various functions. Parameters are supplied to `github-actions` using environment variables in the form described by the GitHub Actions documentation. `github-actions` uses some of the default GitHub Actions environment variables as described in the individual commands section.

## Commands

Commands can be called using `docker run docker/github-actions {command}`

### login

Does a `docker login` using the supplied username and password. Will default to Docker Hub but can be supplied a server address to login to a third-party registry as required.

#### inputs

|Environment Variable|Required|Description|
|---|---|---|
|INPUT_USERNAME|yes|Username to login with|
|INPUT_PASSWORD|yes|Password to login with|
|INPUT_REGISTRY|no|Registry server to login to. Defaults to Docker Hub|

### build

Builds and tags a docker image.

#### inputs

|Environment Variable|Required|Description|
|---|---|---|
|INPUT_PATH|yes|Path to build from|
|INPUT_DOCKERFILE|no|Path to Dockerfile|
|INPUT_ADD_GIT_LABELS|no|Adds git labels (see below)|
|INPUT_TARGET|no|Target build stage to build|
|INPUT_BUILD_ARGS|no|Comma-delimited list of build-args|
|INPUT_LABELS|no|Comma-delimited list of labels|

See the tagging section for information on tag inputs

##### Git labels

When `INPUT_ADD_GIT_LABELS` is `true` labels are automatically added to the image that contain data about the current state of the git repo:

|Label|Description|
|---|---|
|com.docker.github-actions-actor|The username of the user that kicked off this run of the actions (e.g. the user that did the git push)|
|com.docker.github-actions-sha|The full git sha of this commit|

### push

Pushes a docker image.

#### inputs

See the tagging section for information on tag inputs

Choose a reason for hiding this comment

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

Eventually we should make these links
See the [tagging section](https://github.com/docker/github-actions/README.md#Tagging)
or however that works

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Indeed. Will get round to it once the inputs and tags have been finalized



### build-push

Builds, logs in, and pushes a docker image.

#### inputs

Same as the login and build commands with the addition of

|Environment Variable|Required|Description|
|---|---|---|
|INPUT_PUSH|no|Will push the image if true|


## Tagging

Tagging of images can be set manually, left to `github-actions` to automate, or a combination of the both.

There are 4 input variables used for tagging

|Environment Variable|Required|Description|
|---|---|---|
|INPUT_REGISTRY|no|Registry server to tag with|
|INPUT_REPOSITORY|yes|Repository to tag with|
|INPUT_TAGS|no|Hard coded comma-delimited list of tags|
|INPUT_TAG_WITH_REF|no|If true then `github-actions` will add tags depending on the git ref automatically as described below|
|INPUT_TAG_WITH_SHA|no|If true then `github-actions` will add a tag in the form `sha-{git-short-sha}`|

If `INPUT_REGISTRY` is set then all tags are prefixed with `{INPUT_REGISTRY}/{INPUT_REPOSITORY}:`.
If not then all tags are prefixed with `{INPUT_REPOSITORY}:`

Auto tags depend on the git reference that the run is associated with. The reference is passed to `github-actions` using the GitHub actions `GITHUB_REF` enviroment variable.

If the reference is `refs/heads/{branch-name}` then the tag `{branch-name}` is added. For the master branch the `{branch-name}` is replaced with `latest`.

If the reference is `refs/pull-requests/{pr}` then the tag `pr-{pr}` is added.

If the reference is `refs/tags/{tag-name}` then the tag `{tag-name}` is added.

Any `/` in the auto tags are replaced with `-`.

For example if the environment variables are as follows:

|Variable|Value|
|---|---|
|INPUT_REGISTRY||
|INPUT_REPOSITORY|myorg/myimage|
|INPUT_TAGS|foo,bar|
|INPUT_TAG_WITH_REF|true|
|GITHUB_REF|refs/tags/v0.1|

Then the image will be tagged with:
```
myorg/myimage:foo
myorg/myimage:bar
myorg/myimage:v0.1
```

If the variables are as follows:

|Variable|Value|
|---|---|
|INPUT_REGISTRY|myregistry|
|INPUT_REPOSITORY|myorg/myimage|
|INPUT_TAGS|foo,bar|
|INPUT_TAG_WITH_REF|true|
|INPUT_TAG_WITH_SHA|true|
|GITHUB_REF|refs/heads/master|
|GITHUB_SHA|c6df8c68eb71799f9c9ab4a4a4650d6aabd7e415|

Then the image will be tagged with:
```
myregistry/myorg/myimage:foo
myregistry/myorg/myimage:bar
myregistry/myorg/myimage:lastest
myregistry/myorg/myimage:c6df8c6
```

## Building github-actions
The code is written in Go v1.13 with `go mod`. It can be built locally using the `Makefile` or in docker using the `docker.Makefile`.

`make -f docker.Makefile` will build the code, check the linting using golangci-lint, run the go tests, and build the image with a tag of docker/github-actions:latest

`make -f docker.Makefile TAG=foo` will build the code, check the linting using golangci-lint, run the go tests, and build the image with a tag of docker/github-actions:foo

`make -f docker.Makefile image` will build the github-actions image without a tag and without running test or lint checking

`make -f docker.Makefile cli` will build the cli and copy it to `./bin/github-actions`

`make -f docker.Makefile test` will run the go tests
`make -f docker.Makefile test` will run the unit and e2e tests
25 changes: 25 additions & 0 deletions cmd/build.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package main

import (
"github.com/docker/github-actions/internal/command"
"github.com/docker/github-actions/internal/options"
)

func build(cmd command.Runner) error {
o, err := options.GetBuildOptions()
if err != nil {
return err
}

github, err := options.GetGitHubOptions()
if err != nil {
return err
}

tags, err := options.GetTags(options.GetRegistry(), github)
if err != nil {
return err
}

return command.RunBuild(cmd, o, github, tags)
}
43 changes: 43 additions & 0 deletions cmd/build_push.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package main

import (
"github.com/docker/github-actions/internal/command"
"github.com/docker/github-actions/internal/options"
)

func buildPush(cmd command.Runner) error {
github, err := options.GetGitHubOptions()
if err != nil {
return err
}

registry := options.GetRegistry()
tags, err := options.GetTags(registry, github)
if err != nil {
return err
}

build, err := options.GetBuildOptions()
if err != nil {
return err
}
if err = command.RunBuild(cmd, build, github, tags); err != nil {
return err
}

if shouldPush, err := options.ShouldPush(); err != nil {
return err
} else if shouldPush {
login, err := options.GetLoginOptions()
if err != nil {
return err
}
if login.Username != "" && login.Password != "" {
if err := command.RunLogin(cmd, login, registry); err != nil {
return err
}
}
}

return command.RunPush(cmd, tags)
}
15 changes: 15 additions & 0 deletions cmd/login.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package main

import (
"github.com/docker/github-actions/internal/command"
"github.com/docker/github-actions/internal/options"
)

func login(cmd command.Runner) error {
o, err := options.GetLoginOptions()
if err != nil {
return err
}

return command.RunLogin(cmd, o, options.GetRegistry())
}
51 changes: 45 additions & 6 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,56 @@ import (
"fmt"
"os"

commandLine "github.com/urfave/cli/v2"
"github.com/docker/github-actions/internal/command"
"github.com/docker/github-actions/internal/options"
"github.com/spf13/cobra"
)

func main() {
app := &commandLine.App{
Name: "docker github actions",
Usage: "Used in GitHub Actions to run Docker workflows",
_, err := options.GetGitHubOptions()
if err != nil {
fmt.Println(err)
os.Exit(1)
}

err := app.Run(os.Args)
if err != nil {
runner := command.NewRunner()

rootCmd := &cobra.Command{
Use: "github-actions",
Short: "Used in GitHub Actions to run Docker workflows",
}
rootCmd.AddCommand(
&cobra.Command{
Use: "login",
Short: "Logs into a docker registry",
RunE: func(cmd *cobra.Command, args []string) error {
return login(runner)
},
},
&cobra.Command{
Use: "build",
Short: "Builds a docker image",
RunE: func(cmd *cobra.Command, args []string) error {
return build(runner)
},
},
&cobra.Command{
Use: "push",
Short: "Pushes a docker image",
RunE: func(cmd *cobra.Command, args []string) error {
return push(runner)
},
},
&cobra.Command{
Use: "build-push",
Short: "Builds and pushes a docker image to a registry, logging in if necessary",
RunE: func(cmd *cobra.Command, args []string) error {
return buildPush(runner)
},
},
)

if err = rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
Expand Down
Loading