Skip to content
This repository was archived by the owner on Jun 22, 2021. It is now read-only.

Commit 20414ad

Browse files
authored
Merge pull request #2 from docker/spike-first-action
DESKTOP-2412 Github action 1: Write first code to run the action
2 parents f319142 + e93e32e commit 20414ad

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1870
-31
lines changed

.github/workflows/main.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,14 @@ jobs:
99
- name: Checkout
1010
uses: actions/checkout@v2
1111

12+
- name: Print env
13+
run: env
14+
15+
- name: Read event json
16+
run: cat $GITHUB_EVENT_PATH
17+
1218
- name: Build
13-
run: make -f docker.Makefile
19+
run: DOCKER_BUILDKIT=1 make -f docker.Makefile build
20+
21+
- name: E2E
22+
run: DOCKER_BUILDKIT=1 make -f docker.Makefile test-e2e

Dockerfile

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
ARG GO_VERSION=1.13.7
22
ARG GOLANGCI_LINT_VERSION=v1.23.6
3-
ARG ALPINE_VERSION=3.11.3
4-
3+
ARG DND_VERSION=19.03
54

65

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

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

11-
ARG MAKE_TARGET=all
11+
ARG MAKE_TARGET=default
1212
ENV CGO_ENABLED=0
1313
WORKDIR /src
1414

@@ -17,13 +17,31 @@ COPY . .
1717
RUN make ${MAKE_TARGET}
1818

1919

20+
# Used to run e2e tests for github-actions
21+
# This image must be run as a container to run the tests
22+
FROM golang:${GO_VERSION} AS e2e
23+
ARG CLI_CHANNEL=stable
24+
ARG CLI_VERSION=19.03.5
25+
26+
RUN apt-get install -y -q --no-install-recommends coreutils util-linux
27+
28+
ENV CGO_ENABLED=0
29+
ENV GITHUB_ACTIONS_BINARY=/github-actions
30+
WORKDIR /tests
31+
32+
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
33+
34+
COPY . .
35+
COPY --from=builder /src/bin/github-actions /github-actions
2036

37+
38+
# Used to extract the github-actions binary
2139
FROM scratch AS cli
2240
COPY --from=builder /src/bin/github-actions github-actions
2341

2442

25-
26-
FROM alpine:${ALPINE_VERSION}
43+
# The github-actions image that is used by published docker github actions
44+
FROM docker:${DND_VERSION}
2745

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

Makefile

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
all: build lint test
1+
default: build lint test-unit
2+
3+
all: default test-e2e
24

35
build:
46
@$(call mkdir,bin)
@@ -7,5 +9,11 @@ build:
79
lint:
810
golangci-lint run --config golangci.yml ./...
911

10-
test:
11-
go test ./...
12+
test: test-unit test-e2e
13+
14+
test-unit:
15+
go test ./cmd/... ./internal/...
16+
17+
test-e2e: build
18+
docker build --file ./e2e/Dockerfile.registry -t github-actions-registry ./e2e
19+
go test ./e2e/...

README.md

Lines changed: 131 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,143 @@
11
# github-actions
2-
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
2+
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.
33

4+
`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.
5+
6+
## Commands
7+
8+
Commands can be called using `docker run docker/github-actions {command}`
9+
10+
### login
11+
12+
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.
13+
14+
#### inputs
15+
16+
|Environment Variable|Required|Description|
17+
|---|---|---|
18+
|INPUT_USERNAME|yes|Username to login with|
19+
|INPUT_PASSWORD|yes|Password to login with|
20+
|INPUT_REGISTRY|no|Registry server to login to. Defaults to Docker Hub|
21+
22+
### build
23+
24+
Builds and tags a docker image.
25+
26+
#### inputs
27+
28+
|Environment Variable|Required|Description|
29+
|---|---|---|
30+
|INPUT_PATH|yes|Path to build from|
31+
|INPUT_DOCKERFILE|no|Path to Dockerfile|
32+
|INPUT_ADD_GIT_LABELS|no|Adds git labels (see below)|
33+
|INPUT_TARGET|no|Target build stage to build|
34+
|INPUT_BUILD_ARGS|no|Comma-delimited list of build-args|
35+
|INPUT_LABELS|no|Comma-delimited list of labels|
36+
37+
See the tagging section for information on tag inputs
38+
39+
##### Git labels
40+
41+
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:
42+
43+
|Label|Description|
44+
|---|---|
45+
|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)|
46+
|com.docker.github-actions-sha|The full git sha of this commit|
47+
48+
### push
49+
50+
Pushes a docker image.
51+
52+
#### inputs
53+
54+
See the tagging section for information on tag inputs
55+
56+
57+
### build-push
58+
59+
Builds, logs in, and pushes a docker image.
60+
61+
#### inputs
62+
63+
Same as the login and build commands with the addition of
64+
65+
|Environment Variable|Required|Description|
66+
|---|---|---|
67+
|INPUT_PUSH|no|Will push the image if true|
68+
69+
70+
## Tagging
71+
72+
Tagging of images can be set manually, left to `github-actions` to automate, or a combination of the both.
73+
74+
There are 4 input variables used for tagging
75+
76+
|Environment Variable|Required|Description|
77+
|---|---|---|
78+
|INPUT_REGISTRY|no|Registry server to tag with|
79+
|INPUT_REPOSITORY|yes|Repository to tag with|
80+
|INPUT_TAGS|no|Hard coded comma-delimited list of tags|
81+
|INPUT_TAG_WITH_REF|no|If true then `github-actions` will add tags depending on the git ref automatically as described below|
82+
|INPUT_TAG_WITH_SHA|no|If true then `github-actions` will add a tag in the form `sha-{git-short-sha}`|
83+
84+
If `INPUT_REGISTRY` is set then all tags are prefixed with `{INPUT_REGISTRY}/{INPUT_REPOSITORY}:`.
85+
If not then all tags are prefixed with `{INPUT_REPOSITORY}:`
86+
87+
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.
88+
89+
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`.
90+
91+
If the reference is `refs/pull-requests/{pr}` then the tag `pr-{pr}` is added.
92+
93+
If the reference is `refs/tags/{tag-name}` then the tag `{tag-name}` is added.
94+
95+
Any `/` in the auto tags are replaced with `-`.
96+
97+
For example if the environment variables are as follows:
98+
99+
|Variable|Value|
100+
|---|---|
101+
|INPUT_REGISTRY||
102+
|INPUT_REPOSITORY|myorg/myimage|
103+
|INPUT_TAGS|foo,bar|
104+
|INPUT_TAG_WITH_REF|true|
105+
|GITHUB_REF|refs/tags/v0.1|
106+
107+
Then the image will be tagged with:
108+
```
109+
myorg/myimage:foo
110+
myorg/myimage:bar
111+
myorg/myimage:v0.1
112+
```
113+
114+
If the variables are as follows:
115+
116+
|Variable|Value|
117+
|---|---|
118+
|INPUT_REGISTRY|myregistry|
119+
|INPUT_REPOSITORY|myorg/myimage|
120+
|INPUT_TAGS|foo,bar|
121+
|INPUT_TAG_WITH_REF|true|
122+
|INPUT_TAG_WITH_SHA|true|
123+
|GITHUB_REF|refs/heads/master|
124+
|GITHUB_SHA|c6df8c68eb71799f9c9ab4a4a4650d6aabd7e415|
125+
126+
Then the image will be tagged with:
127+
```
128+
myregistry/myorg/myimage:foo
129+
myregistry/myorg/myimage:bar
130+
myregistry/myorg/myimage:lastest
131+
myregistry/myorg/myimage:c6df8c6
132+
```
4133

5134
## Building github-actions
6135
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`.
7136

8137
`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
9138

10-
`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
11-
12139
`make -f docker.Makefile image` will build the github-actions image without a tag and without running test or lint checking
13140

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

16-
`make -f docker.Makefile test` will run the go tests
143+
`make -f docker.Makefile test` will run the unit and e2e tests

cmd/build.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package main
2+
3+
import (
4+
"github.com/docker/github-actions/internal/command"
5+
"github.com/docker/github-actions/internal/options"
6+
)
7+
8+
func build(cmd command.Runner) error {
9+
o, err := options.GetBuildOptions()
10+
if err != nil {
11+
return err
12+
}
13+
14+
github, err := options.GetGitHubOptions()
15+
if err != nil {
16+
return err
17+
}
18+
19+
tags, err := options.GetTags(options.GetRegistry(), github)
20+
if err != nil {
21+
return err
22+
}
23+
24+
return command.RunBuild(cmd, o, github, tags)
25+
}

cmd/build_push.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package main
2+
3+
import (
4+
"github.com/docker/github-actions/internal/command"
5+
"github.com/docker/github-actions/internal/options"
6+
)
7+
8+
func buildPush(cmd command.Runner) error {
9+
github, err := options.GetGitHubOptions()
10+
if err != nil {
11+
return err
12+
}
13+
14+
registry := options.GetRegistry()
15+
tags, err := options.GetTags(registry, github)
16+
if err != nil {
17+
return err
18+
}
19+
20+
build, err := options.GetBuildOptions()
21+
if err != nil {
22+
return err
23+
}
24+
if err = command.RunBuild(cmd, build, github, tags); err != nil {
25+
return err
26+
}
27+
28+
if shouldPush, err := options.ShouldPush(); err != nil {
29+
return err
30+
} else if shouldPush {
31+
login, err := options.GetLoginOptions()
32+
if err != nil {
33+
return err
34+
}
35+
if login.Username != "" && login.Password != "" {
36+
if err := command.RunLogin(cmd, login, registry); err != nil {
37+
return err
38+
}
39+
}
40+
}
41+
42+
return command.RunPush(cmd, tags)
43+
}

cmd/login.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package main
2+
3+
import (
4+
"github.com/docker/github-actions/internal/command"
5+
"github.com/docker/github-actions/internal/options"
6+
)
7+
8+
func login(cmd command.Runner) error {
9+
o, err := options.GetLoginOptions()
10+
if err != nil {
11+
return err
12+
}
13+
14+
return command.RunLogin(cmd, o, options.GetRegistry())
15+
}

cmd/main.go

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,56 @@ import (
44
"fmt"
55
"os"
66

7-
commandLine "github.com/urfave/cli/v2"
7+
"github.com/docker/github-actions/internal/command"
8+
"github.com/docker/github-actions/internal/options"
9+
"github.com/spf13/cobra"
810
)
911

1012
func main() {
11-
app := &commandLine.App{
12-
Name: "docker github actions",
13-
Usage: "Used in GitHub Actions to run Docker workflows",
13+
_, err := options.GetGitHubOptions()
14+
if err != nil {
15+
fmt.Println(err)
16+
os.Exit(1)
1417
}
1518

16-
err := app.Run(os.Args)
17-
if err != nil {
19+
runner := command.NewRunner()
20+
21+
rootCmd := &cobra.Command{
22+
Use: "github-actions",
23+
Short: "Used in GitHub Actions to run Docker workflows",
24+
}
25+
rootCmd.AddCommand(
26+
&cobra.Command{
27+
Use: "login",
28+
Short: "Logs into a docker registry",
29+
RunE: func(cmd *cobra.Command, args []string) error {
30+
return login(runner)
31+
},
32+
},
33+
&cobra.Command{
34+
Use: "build",
35+
Short: "Builds a docker image",
36+
RunE: func(cmd *cobra.Command, args []string) error {
37+
return build(runner)
38+
},
39+
},
40+
&cobra.Command{
41+
Use: "push",
42+
Short: "Pushes a docker image",
43+
RunE: func(cmd *cobra.Command, args []string) error {
44+
return push(runner)
45+
},
46+
},
47+
&cobra.Command{
48+
Use: "build-push",
49+
Short: "Builds and pushes a docker image to a registry, logging in if necessary",
50+
RunE: func(cmd *cobra.Command, args []string) error {
51+
return buildPush(runner)
52+
},
53+
},
54+
)
55+
56+
if err = rootCmd.Execute(); err != nil {
1857
fmt.Println(err)
1958
os.Exit(1)
2059
}

0 commit comments

Comments
 (0)