Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
baksetercx committed Aug 8, 2024
1 parent 260b043 commit e2e10ad
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 46 deletions.
45 changes: 26 additions & 19 deletions build/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ inputs:
namespace:
description: 'Namespace or system of the application. This is only relevant for Elvia applications.'
required: false
csproj-file:
project-file:
description: |
Path to a csproj-file, e.g. `src/my-app/my-app.csproj`.
Path to a `.csproj`-file for .NET, or a `go.mod` file for Go.
E.g. `src/my-app/my-app.csproj` or `src/my-app/go.mod`.
Either this or `dockerfile` must be given.
This argument takes precedence over `dockerfile`.'
required: false
dockerfile:
description: 'Path to Dockerfile, e.g. `src/Dockerfile`. Either this or `csproj-file` must be given.'
description: 'Path to Dockerfile, e.g. `src/Dockerfile`. Either this or `project-file` must be given.'
default: 'Dockerfile'
required: false
docker-build-context:
Expand Down Expand Up @@ -106,14 +107,21 @@ runs:
uses: actions/checkout@v4

- name: Generate Dockerfile
id: generate_dockerfile
if: ${{ inputs.csproj-file != '' }}
id: generate-dockerfile
if: ${{ inputs.project-file != '' }}
shell: bash
run: |
# Generate Dockerfile
python '${{ github.action_path }}/create_dockerfile.py'
env:
CSPROJ_FILE: ${{ inputs.csproj-file }}
if [[ '${{ inputs.project-file }}' == *csproj ]]; then
export CSPROJ_FILE='${{ inputs.project-file }}'
python '${{ github.action_path }}/create_dockerfile.py'
elif [[ '${{ inputs.project-file }}' == *go.mod ]]; then
export GO_MOD_FILE='${{ inputs.project-file }}'
python '${{ github.action_path }}/create_dockerfile.py'
else
echo 'Invalid project-file. Must be either a .csproj or a go.mod file.'
exit 1
fi
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
Expand Down Expand Up @@ -156,8 +164,8 @@ runs:
} >> "$GITHUB_ENV"
fi
if [[ '${{ inputs.csproj-file }}' == '' && '${{ inputs.dockerfile }}' == '' ]]; then
echo 'Either csproj-file or dockerfile must be given.'
if [[ '${{ inputs.project-file }}' == '' && '${{ inputs.dockerfile }}' == '' ]]; then
echo 'Either project-file or dockerfile must be given.'
exit 1
fi
Expand All @@ -171,19 +179,18 @@ runs:
exit 1
fi
if [[ -z '${{ inputs.docker-build-context }}' ]]; then
DOCKER_DIR=$(dirname '${{ inputs.dockerfile }}') # default to the directory of the Dockerfile
else
DOCKER_DIR='${{ inputs.docker-build-context }}'
fi
echo "DOCKER_DIR=$DOCKER_DIR" >> "$GITHUB_ENV"
if [[ -z '${{ steps.generate_dockerfile.outputs.DOCKERFILE }}' ]]; then
if [[ -z '${{ steps.generate-dockerfile.outputs.DOCKERFILE }}' ]]; then
DOCKERFILE='${{ inputs.dockerfile }}'
DOCKER_DIR=$(dirname '${{ inputs.dockerfile }}')
else
DOCKERFILE='${{ steps.generate_dockerfile.outputs.DOCKERFILE }}'
DOCKERFILE='${{ steps.generate-dockerfile.outputs.DOCKERFILE }}'
DOCKER_DIR=$(dirname '${{ inputs.project-file }}')
fi
if [[ '${{ inputs.docker-build-context }}' != '' ]]; then
DOCKER_DIR='${{ inputs.docker-build-context }}' # override with user input
fi
echo "DOCKERFILE=$DOCKERFILE" >> "$GITHUB_ENV"
echo "DOCKER_DIR=$DOCKER_DIR" >> "$GITHUB_ENV"
if [[ '${{ inputs.docker-build-no-summary }}' == 'true' ]]; then
echo 'DOCKER_BUILD_NO_SUMMARY=true' >> "$GITHUB_ENV"
Expand Down
124 changes: 97 additions & 27 deletions build/create_dockerfile.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# to run locally:
# export CSPROJ_FILE=.github/test/src/core-demo-api.csproj
# export CSPROJ_FILE=.github/test/src/core-demo-api.csproj or export GO_MOD_FILE=go.mod
# export GITHUB_OUTPUT="./tmp/output.txt"
# python3 build/create_dockerfile.py

Expand All @@ -11,7 +11,10 @@
def find_assembly_name(csproj_file):
root = ET.parse(csproj_file).getroot()
if len(root.findall("PropertyGroup/AssemblyName")) > 0:
return root.findall("PropertyGroup/AssemblyName")[-1].text + ".dll"
assembly_name = root.findall("PropertyGroup/AssemblyName")[-1].text
if not isinstance(assembly_name, str):
raise ValueError("Unable to find AssemblyName in csproj-file")
return f"{assembly_name}.dll"
else:
return os.path.splitext(os.path.basename(csproj_file))[0] + ".dll"

Expand All @@ -21,7 +24,9 @@ def find_docker_base_image_tag(csproj_file):
if len(root.findall("PropertyGroup/TargetFramework")) > 0:
# .NET 8.0
framework = root.findall("PropertyGroup/TargetFramework")[-1].text
tag = framework[3:] + "-alpine"
if not isinstance(framework, str):
raise ValueError("Unable to find TargetFramework in csproj-file")
tag = f"{framework[3:]}-alpine"
return tag
else:
raise ValueError("Unable to find TargetFramework in csproj-file")
Expand All @@ -30,7 +35,7 @@ def find_docker_base_image_tag(csproj_file):
def find_docker_runtime_base_image(csproj_file):
root = ET.parse(csproj_file).getroot()
if "Sdk" not in root.attrib:
raise ValueError("Unable to find Sdk in csproj-file")
raise ValueError("Unable to find SDK in csproj-file")
sdk = root.attrib["Sdk"]
if sdk in ["Microsoft.NET.Sdk"]:
return "mcr.microsoft.com/dotnet/runtime"
Expand Down Expand Up @@ -102,31 +107,96 @@ def write_dockerfile(
print("Dockerfile:\n" + f.read())


def write_dockerfile_go(go_mod_path, filename):
with open(os.environ["GITHUB_OUTPUT"], "a") as fh:
key = "DOCKERFILE"
print(f"{key}={filename}", file=fh)

template = """FROM golang:alpine AS build
LABEL maintainer="[email protected]"
ENV GO111MODULE=on CGO_ENABLED=0 GOOS=linux GOARCH=amd64
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY *.go ./
RUN go build -o ./out/executable .
FROM alpine:latest
LABEL maintainer="[email protected]"
RUN addgroup application-group --gid 1001 && \\
adduser application-user --uid 1001 \\
--ingroup application-group \\
--disabled-password
WORKDIR /app
COPY --from=build /app/out .
RUN chown --recursive application-user .
USER application-user
EXPOSE 8080
ENTRYPOINT ["./executable"]
"""
context = {"go_mod_path": go_mod_path}
with open(filename,
"w") as f:
f.write(template.format(**context))

f = open(filename, "a")
f.write(
"""
"""
)
f.close()


def main():
csproj_file = os.environ.get("CSPROJ_FILE")
if csproj_file is None:
raise ValueError("Missing required Environment Variable CSPROJ_FILE")
print("csproj_file: " + csproj_file)
csproj_file = csproj_file.strip("'\" ")

directory = os.path.join("tmp", str(uuid.uuid4()))
os.makedirs(directory)
filename = os.path.join(directory, "Dockerfile")
print("filename: " + filename)

assembly_name = find_assembly_name(csproj_file)
print("assembly name: " + assembly_name)
docker_base_image_tag = find_docker_base_image_tag(csproj_file)
print("base image tag: " + docker_base_image_tag)
docker_runtime_base_image = find_docker_runtime_base_image(csproj_file)
print("runtime base image: " + docker_runtime_base_image)
write_dockerfile(
csproj_file,
assembly_name,
docker_base_image_tag,
docker_runtime_base_image,
filename,
)
go_mod_file = os.environ.get("GO_MOD_FILE")

if csproj_file is not None:
print("csproj_file: " + csproj_file)
csproj_file = csproj_file.strip("'\" ")

directory = os.path.join("tmp", str(uuid.uuid4()))
os.makedirs(directory)
filename = os.path.join(directory, "Dockerfile")
print("filename: " + filename)

assembly_name = find_assembly_name(csproj_file)
print("assembly name: " + assembly_name)
docker_base_image_tag = find_docker_base_image_tag(csproj_file)
print("base image tag: " + docker_base_image_tag)
docker_runtime_base_image = find_docker_runtime_base_image(csproj_file)
print("runtime base image: " + docker_runtime_base_image)
write_dockerfile(
csproj_file,
assembly_name,
docker_base_image_tag,
docker_runtime_base_image,
filename,
)
elif go_mod_file is not None:
print("go_mod_file: " + go_mod_file)
go_mod_file = go_mod_file.strip("'\" ")
go_mod_path = os.path.dirname(go_mod_file)

directory = os.path.join("tmp", str(uuid.uuid4()))
os.makedirs(directory)
filename = os.path.join(directory, "Dockerfile")
print("filename: " + filename)

write_dockerfile_go(go_mod_path, filename)
else:
raise ValueError("CSPROJ_FILE or GO_MOD_FILE must be set.")


if __name__ == "__main__":
Expand Down

0 comments on commit e2e10ad

Please sign in to comment.