From 055ff7ef17cbcc9cb97e6f4e0b6183d3bae32329 Mon Sep 17 00:00:00 2001 From: slylii Date: Tue, 13 Dec 2022 17:59:03 +0700 Subject: [PATCH 1/2] github-actions --- .github/actions/build_image/action.yaml | 25 ++++++++++++++++ .github/workflows/build_all.yaml | 23 ++++++++++++++ .github/workflows/ci.yaml | 40 +++++++++++++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 .github/actions/build_image/action.yaml create mode 100644 .github/workflows/build_all.yaml create mode 100644 .github/workflows/ci.yaml diff --git a/.github/actions/build_image/action.yaml b/.github/actions/build_image/action.yaml new file mode 100644 index 0000000..8c685ca --- /dev/null +++ b/.github/actions/build_image/action.yaml @@ -0,0 +1,25 @@ +name: "Build docker image" +description: "Action to build docker image" +inputs: + image: + description: "image:tag" + required: true + dockerfile: + description: "Dockerfile to use" + required: true + default: "Dockerfile" + target: + description: "target to build" + required: false + default: "" + context: + description: "context" + required: true + default: "." +outputs: {} +runs: + using: "composite" + steps: + - run: | + docker build -t ${{ inputs.image }} -f ${{ inputs.dockerfile }} --target ${{ inputs.target }} ${{ inputs.context }} + shell: bash \ No newline at end of file diff --git a/.github/workflows/build_all.yaml b/.github/workflows/build_all.yaml new file mode 100644 index 0000000..185450c --- /dev/null +++ b/.github/workflows/build_all.yaml @@ -0,0 +1,23 @@ +name: Build all variants of docker images +on: + push: {} + +jobs: + build: + strategy: + matrix: + base_image: + - ubuntu + target: + - builder + - release + runs-on: ubuntu-latest + steps: + - name: Check out Project + uses: actions/checkout@v3 + + - name: build + uses: ./.github/actions/build_image + with: + image: ${{ matrix.target }}:${{ matrix.base_image }} + target: ${{ matrix.target }} \ No newline at end of file diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..680fb85 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,40 @@ +name: CI workflow +on: + push: {} + workflow_dispatch: + inputs: + tag: + default: latest + description: image tag + +jobs: + build: + runs-on: ubuntu-latest + env: + BUILDER_IMAGE: cv-builder + RELEASE_IMAGE: cv + TAG: "${{ inputs.tag != '' && inputs.tag || github.ref_name }}" + BASE_IMAGE: "${{ inputs.base_image != '' && inputs.base_image || 'ubuntu' }}" + steps: + - name: Check out Project + uses: actions/checkout@v3 + + - name: Build builder image + uses: docker/build-push-action@v3 + with: + context: . + file: ./Dockerfile + push: false + tags: ${{ env.BUILDER_IMAGE }}:${{ env.TAG }} + target: builder + + - name: Test + run: | + docker run --rm ${{ env.BUILDER_IMAGE }}:${{ env.TAG }} json + - name: Build release image + uses: docker/build-push-action@v3 + with: + context: . + file: ./Dockerfile + push: false + tags: ${{ env.BUILDER_IMAGE }}:${{ env.TAG }} \ No newline at end of file From 874ed8d5a67ad6fb7fa207619b44360dddacdff5 Mon Sep 17 00:00:00 2001 From: slylii Date: Tue, 13 Dec 2022 20:05:57 +0700 Subject: [PATCH 2/2] files --- .env | 3 +++ .gitignore | 6 +++++ .pre-commit-config.yaml | 11 ++++++++ CHANGELOG.md | 18 +++++++++++++ Dockerfile | 41 ++++++++++++++++++++++++++++ Jenkinsfile | 48 +++++++++++++++++++++++++++++++++ Taskfile.yaml | 55 ++++++++++++++++++++++++++++++++++++++ config/nginx/balancer.conf | 8 ++++++ config/nginx/worker.conf | 8 ++++++ docker-compose.yaml | 31 +++++++++++++++++++++ scripts/build.sh | 23 ++++++++++++++++ scripts/generate_cv.sh | 32 ++++++++++++++++++++++ src/skills.yaml | 53 ++++++++++++++++++++++++++++++++++++ src/yamlcv.yaml | 18 +++++++++++++ 14 files changed, 355 insertions(+) create mode 100644 .env create mode 100644 .gitignore create mode 100644 .pre-commit-config.yaml create mode 100644 CHANGELOG.md create mode 100644 Dockerfile create mode 100644 Jenkinsfile create mode 100644 Taskfile.yaml create mode 100644 config/nginx/balancer.conf create mode 100644 config/nginx/worker.conf create mode 100644 docker-compose.yaml create mode 100644 scripts/build.sh create mode 100644 scripts/generate_cv.sh create mode 100644 src/skills.yaml create mode 100644 src/yamlcv.yaml diff --git a/.env b/.env new file mode 100644 index 0000000..4dee00b --- /dev/null +++ b/.env @@ -0,0 +1,3 @@ +SRC_PATH=src +BUILD_PATH=build +CV=cv diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8dffd77 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*.html +*.json +*.pdf +build +build/* +.idea diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..5edff18 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,11 @@ +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v2.3.0 + hooks: + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace +- repo: https://github.com/psf/black + rev: 21.12b0 + hooks: + - id: black diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..f486a3c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,18 @@ +# v1.1.0 + +Added: +- Automated with Taskfile + +Fixed: +- yq setup instructions + +# v1.0.0 + +Added: +- skill additional metadata support +- build automation + +# v0.1.0 + +Added: +- CV Yaml in yaml-cv structure diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7b59a09 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,41 @@ +FROM ubuntu:22.04 as builder + +WORKDIR /app + +ARG VERSION=v4.9.6 +ARG BINARY=yq_linux_386 +ARG TASK_VERSION=v3.17.0 +ARG TASK_BINARY=task_linux_amd64.tar.gz + +RUN apt-get update && apt-get install -y \ + npm \ + wget \ + wkhtmltopdf \ + libfontconfig1 \ + libxtst6 \ + rubygems \ + && rm -rf /var/lib/apt/lists/* + +ARG VERSION=v4.9.6 +ARG BINARY=yq_linux_386 +RUN wget https://github.com/mikefarah/yq/releases/download/${VERSION}/${BINARY} -O /usr/bin/yq \ + && chmod +x /usr/bin/yq + +RUN wget -O- https://github.com/go-task/task/releases/download/${TASK_VERSION}/${TASK_BINARY} \ + | tar xz -C /usr/bin + + +COPY src/ src/ +COPY scripts/ scripts/ +COPY Taskfile.yaml Taskfile.yaml +COPY .env .env + +ENTRYPOINT ["/usr/bin/task"] + +FROM builder as build +RUN task build + +FROM busybox as release +WORKDIR /app +COPY --from=build /app/build/cv.html cv.html +VOLUME /app \ No newline at end of file diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..f4658e2 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,48 @@ +pipeline { + + agent { + node { + label 'docker' + } + } + + parameters { + string(name: 'IMAGE_TAG', defaultValue: "", description: '') + } + + environment { + TAG = "${params.IMAGE_TAG != "" ? "${params.IMAGE_TAG}" : "${GIT_COMMIT}"}" + } + + stages { + + stage("Begin") { + steps { + checkout scm + } + } + + stage('Builder image and test') { + steps { + script { + + builderImage = docker.build("cv-builder:${TAG}") + builderImage.withRun {c -> + "json" + } + } + } + } + + stage('Release image') { + steps { + script { + docker.build("cv:${TAG}") + } + } + } + + + } + +} \ No newline at end of file diff --git a/Taskfile.yaml b/Taskfile.yaml new file mode 100644 index 0000000..669eee8 --- /dev/null +++ b/Taskfile.yaml @@ -0,0 +1,55 @@ +version: '3' + +dotenv: ['.env'] + +env: + IMAGE_TAG: '{{ .IMAGE_TAG | default "test" }}' + PROJECT: '{{ .PROJECT | default "cv" }}' + + tasks: + build: + cmds: + - scripts/build.sh + + json: + deps: + - build + cmds: + - yq '. | to_json' {{ .BUILD_PATH }}/{{ .CV }}.yaml > {{ .BUILD_PATH }}/{{ .CV }}.json + + skill_by_level: + env: + LEVEL: ".LEVEL" + cmds: + - yq '.skills[] | select(.level == "{{ .LEVEL }}") | .name' {{ .SRC_PATH }}/skills.yaml + + + docker-builder: + cmds: + - docker build -t cv-builder:{{ .IMAGE_TAG }} --target builder . + + docker-release: + docker build -t cv:{{ .IMAGE_TAG }} . + + docker-build: + cmds: + - task: docker-builder + - task: docker-release + + docker-run-task: + deps: + - docker-builder + cmds: + - docker run --rm -ti cv-builder:{{ .IMAGE_TAG }} {{.CLI_ARGS}} + + docker-server-foreground: + docker-compose -p {{ .PROJECT }} up + + docker-server-background: + docker-compose -p {{ .PROJECT }} up -d + + docker-server-stop: + docker-compose -p {{ .PROJECT }} down -v --remove-orphans + + test-ha-server: + while true; do curl -v http://localhost:8080 & sleep 1; done; diff --git a/config/nginx/balancer.conf b/config/nginx/balancer.conf new file mode 100644 index 0000000..7762096 --- /dev/null +++ b/config/nginx/balancer.conf @@ -0,0 +1,8 @@ +server { + listen 80; + resolver 127.0.0.11 ipv6=off valid=10s; + set $backend "http://worker"; + location / { + proxy_pass $backend; + } +} \ No newline at end of file diff --git a/config/nginx/worker.conf b/config/nginx/worker.conf new file mode 100644 index 0000000..f922e5f --- /dev/null +++ b/config/nginx/worker.conf @@ -0,0 +1,8 @@ +server { + listen 80; + + location / { + root /usr/share/nginx/html; + index cv.html; + } +} \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..47ab777 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,31 @@ +services: + cv: + build: + context: . + dockerfile: Dockerfile.ubuntu + target: release + volumes: + - cv:/app + + worker: + depends_on: + - cv + image: nginx:1.23.2-alpine + deploy: + replicas: 3 + volumes: + - ./config/nginx/worker.conf:/etc/nginx/conf.d/default.conf + - cv:/usr/share/nginx/html + - cv:/app + + balancer: + depends_on: + - worker + ports: + - 8080:80 + image: nginx:1.23.2-alpine + volumes: + - ./config/nginx/balancer.conf:/etc/nginx/conf.d/default.conf + +volumes: + cv: \ No newline at end of file diff --git a/scripts/build.sh b/scripts/build.sh new file mode 100644 index 0000000..d4ba700 --- /dev/null +++ b/scripts/build.sh @@ -0,0 +1,23 @@ +#!/bin/bash +set -e + +SCRIPT_DIR=$(readlink -f $(dirname $BASH_SOURCE)) +ROOT_DIR=$(readlink -f "$SCRIPT_DIR/..") +BUILD_PATH="$ROOT_DIR/$BUILD_PATH" + +source $ROOT_DIR/.env + +echo "Building yamlcv" +$SCRIPT_DIR/generate_cv.sh + +CV_YAML="$BUILD_PATH/$CV.yaml" +CV_HTML="$BUILD_PATH/$CV.html" +CV_PDF="$BUILD_PATH/$CV.pdf" + +echo "Building HTML from $CV_YAML" +yaml-cv yaml-cv $CV_YAML > $BUILD_PATH/${CV}.html + +echo "Building PDF from $CV" +yaml-cv yaml-cv $CV_YAML --pdf $BUILD_PATH/${CV}.pdf + +echo "Check files in ./$BUILD_PATH directory" diff --git a/scripts/generate_cv.sh b/scripts/generate_cv.sh new file mode 100644 index 0000000..39de670 --- /dev/null +++ b/scripts/generate_cv.sh @@ -0,0 +1,32 @@ +#!/bin/bash +set -e + +SCRIPT_DIR=$(readlink -f $(dirname $BASH_SOURCE)) +ROOT_DIR=$(readlink -f "$SCRIPT_DIR/..") + +source $ROOT_DIR/.env +SRC_PATH="$ROOT_DIR/$SRC_PATH" +BUILD_PATH="$ROOT_DIR/$BUILD_PATH" + +mkdir -p $BUILD_PATH + +SKILLS="$SRC_PATH/skills.yaml" +YAMLCV="$SRC_PATH/yamlcv.yaml" +CV_YAML="$BUILD_PATH/${CV}.yaml" + +echo 'cleanup' +rm -vf $BUILD_PATH/* 2>/dev/null +echo 'copy template' +cp -v $YAMLCV $CV_YAML + +IFS=$'\n' +CATEGORIES=$(yq '.. comments="" | explode(.) | .categories[]' $SKILLS) + +for CATEGORY in $CATEGORIES; do + export CATEGORY + export ITEMS=$(yq '.. comments="" | explode(.) | .skills[] | select(.category == env(CATEGORY)) | .name as $item ireduce ([]; . + $item) | join(",") ' $SKILLS | uniq) + echo "updating '$CATEGORY' items in $CV_YAML" + yq -i '.technical += {"category": env(CATEGORY), "items": env(ITEMS)}' $CV_YAML +done + +echo "Successfully built $CV_YAML" diff --git a/src/skills.yaml b/src/skills.yaml new file mode 100644 index 0000000..795f19c --- /dev/null +++ b/src/skills.yaml @@ -0,0 +1,53 @@ +# This file is used to extend skills with additional fields and used +# as source for generating "technical" list in yamlcv.yaml. + +categories: + - &lang # this is YAML Anchor + Languages + - &containers + Containers & Orchestration + - &cicd + CI/CD + - &cloud + Cloud + +skills: +- name: python + level: middle + category: *lang # this is YAML alias + labels: + - programming +- name: golang + level: middle + category: *lang + labels: + - programming +- name: docker + level: middle + labels: + - tools + - technology + category: *containers +- name: docker-compose + level: middle + category: *containers + labels: + - tools +- name: k8s + level: middle + category: *containers + labels: + - technology +- name: jenkins + level: middle + category: *cicd + labels: + - tools +- name: GitHub Actions + level: middle + category: *cicd + labels: + - tools +- name: AWS + level: middle + category: *cloud diff --git a/src/yamlcv.yaml b/src/yamlcv.yaml new file mode 100644 index 0000000..91e6ec2 --- /dev/null +++ b/src/yamlcv.yaml @@ -0,0 +1,18 @@ +# structure is based on yaml-cv +# https://github.com/haath/yaml-cv + +details: + first_name: Name + last_name: Lastname + title: DevOps engineer + +profile: | + Focused, energetic and motivated to learn DevOps. + +contact: +- text: my@domain.net + url: "mailto:my@domain.net" + icon: email + +# automatically populated with data from skills.yaml +technical: []