Skip to content

CI workflow to create Github Docker Package after Successfull tests on commit #53

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
135 changes: 135 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
name: CI Pipeline

on:
push:
branches:
- master

jobs:
test-and-build:
runs-on: ubuntu-latest

steps:
# Bonus: STEAP 1 - Record time of job forund here - https://stackoverflow.com/a/72175840
# - name: Set start timestamp
# id: start
# run: |
# printf 'timestamp=%(%s)T\n' >> "$GITHUB_OUTPUT"

- name: Checkout code
uses: actions/checkout@v2

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20.15.0

- name: Install packages
run: npm install
working-directory: angular

- name: Lint code
run: npm run lint
working-directory: angular

- name: Run tests
# No need for "continue-on-error: false" as it is Github Actions default
run: npm run coverage # "1.0.4" - npm run coverage would open browser so added "browsers": "ChromeHeadless" TO angular.json
working-directory: angular

- name: Build
if: success()
run: npm run build
working-directory: angular

# Github Packages explanation https://youtu.be/t3xRLAA_Y7Y
# Example of docker/setup-buildx-action https://dev.to/ken_mwaura1/automate-docker-image-builds-and-push-to-github-registry-using-github-actions-4h20

# Set up Docker Buildx
- name: Set up Docker Buildx
if: success()
uses: docker/setup-buildx-action@v3

# Log in to GitHub Container Registry
- name: Log in to GitHub Container Registry
if: success()
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GHUB_TOKEN }}

# Got from https://cicube.io/workflow-hub/docker-build-push-action/#how-to-push-docker-images-to-github-container-registry-with-github-actions .
- name: Build and push Docker image
if: success()
uses: docker/build-push-action@v2
with:
context: .
push: true
# Error: buildx failed with: ERROR: invalid tag "ghcr.io/Amexei/angular-react-starter:latest": repository name must be lowercase
# Can't use github.repository as it's in uppercase my name Amexei
#
# Have to manually attach package to repository so it is visible inside repo https://stackoverflow.com/questions/73485013/github-package-successfully-published-but-not-showing-up-in-packages-section
tags: ghcr.io/${{ secrets.GHUB_REPOSITORY }}:lastest

# Bonus: STEP 2 - Record time of job forund here - https://stackoverflow.com/a/72175840
# - name: Set start timestamp
# id: duration
# run: |
# printf -v now '%(%s)T'
# duration=$((now - ${{ steps.start.outputs.timestamp }}))

# Bonus calucate time Much easier solution - https://github.com/marketplace/actions/github-workflow-duration-calculator
- name: Calculate Steps Log Time
if: always()
id: duration
uses: RockyIsHere/[email protected]
env:
GITHUB_TOKEN: ${{ secrets.GHUB_TOKEN }}

- name: Print Calculated Time
run: |
echo "Calculated Time: ${{ steps.duration.outputs.duration }}"

# If failure of success - https://stackoverflow.com/a/58859404
# Got an exanole from - https://github.com/go-gitea/gitea/issues/23725#issuecomment-1691883600
# Requires APP_PASSWORD from gmail https://stackoverflow.com/a/70929145
- name: Send success email
if: success()
uses: dawidd6/action-send-mail@v3
with:
server_address: smtp.gmail.com
server_port: 587
username: ${{ secrets.SMTP_USERNAME }}
password: ${{ secrets.SMTP_PASSWORD }}
subject: ${{ github.repository }} ${{ github.workflow }} Success
priority: high
to: ${{ secrets.MAIL_TO }}
from: ${{ secrets.MAIL_FROM }}
convert_markdown: true
html_body: |
### testing-code ${{ job.status }}

*Duration*: ${{ steps.duration.outputs.duration }}

${{ github.repository }}: [${{ github.ref }}@${{ github.sha }}](${{ github.server_url }}/${{ github.repository }}/actions)

- name: Send failure email
if: failure()
uses: dawidd6/action-send-mail@v3
with:
server_address: smtp.gmail.com
server_port: 587
username: ${{ secrets.SMTP_USERNAME }}
password: ${{ secrets.SMTP_PASSWORD }}
subject: ${{ github.repository }} ${{github.workflow}} ${{ job.status }}
priority: high
to: ${{ secrets.MAIL_TO }}
from: ${{ secrets.MAIL_FROM }}
convert_markdown: true
html_body: |
### testing-code ${{ job.status }}

*Duration*: ${{ steps.duration.outputs.duration }}

${{ github.repository }}: [${{ github.ref }}@${{ github.sha }}](${{ github.server_url }}/${{ github.repository }}/actions)
39 changes: 39 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Specifying exact version that I have one my pc as it runs
# https://hub.docker.com/layers/library/node/20.15.0-alpine/images/sha256-89656a128d997717c1e97f9ee32f82274f332f1c6b70a30698cf9afc5ae46ad9

# ✍️ Resources
# https://medium.com/@bidyutnayak10/running-angular-apps-with-nginx-in-docker-anywhere-a-simple-guide-3e951b22f86f
# https://dev.to/oneofthedevs/docker-angular-nginx-37e4


# ⭐ Serving the angular build on nginx server
FROM nginx:alpine

# remove default nginx website
RUN rm -rf /usr/share/nginx/html/*
# Copying dist without node_modules
COPY ./angular/dist/angular-starter/browser/ /usr/share/nginx/html

# Removing default nginx config and adding custom one
RUN rm /etc/nginx/conf.d/default.conf
COPY ./nginx.conf /etc/nginx/conf.d/default.conf

# Default port
EXPOSE 80

# Got from https://medium.com/kocsistem/how-to-run-nginx-for-root-non-root-5ceb13db6d41 "What if we want to run NGINX as non-root user?"
RUN chown -R nginx:nginx /var/cache/nginx && \
chown -R nginx:nginx /var/log/nginx && \
chown -R nginx:nginx /etc/nginx/conf.d
RUN touch /var/run/nginx.pid && \
chown -R nginx:nginx /var/run/nginx.pid

USER nginx

# To check if nginx is running from non-root user
# docker compose up -d
# docker exec -it <container_id> /bin/sh
# RUN ps aux

# This command runs in docker-compose.yml so container doesn't stop
CMD ["nginx", "-g", "daemon off;"]
27 changes: 7 additions & 20 deletions angular/angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,15 @@
"outputPath": "dist/angular-starter",
"index": "src/index.html",
"browser": "src/main.ts",
"polyfills": [
"zone.js"
],
"polyfills": ["zone.js"],
"tsConfig": "tsconfig.app.json",
"assets": [
{
"glob": "**/*",
"input": "public"
}
],
"styles": [
"src/styles.css"
],
"styles": ["src/styles.css"],
"scripts": []
},
"configurations": {
Expand Down Expand Up @@ -79,39 +75,30 @@
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"polyfills": [
"zone.js",
"zone.js/testing"
],
"browsers": "ChromeHeadless",
"polyfills": ["zone.js", "zone.js/testing"],
"tsConfig": "tsconfig.spec.json",
"assets": [
{
"glob": "**/*",
"input": "public"
}
],
"styles": [
"src/styles.css"
],
"styles": ["src/styles.css"],
"scripts": []
}
},
"lint": {
"builder": "@angular-eslint/builder:lint",
"options": {
"lintFilePatterns": [
"src/**/*.ts",
"src/**/*.html"
]
"lintFilePatterns": ["src/**/*.ts", "src/**/*.html"]
}
}
}
}
},
"cli": {
"schematicCollections": [
"@angular-eslint/schematics"
],
"schematicCollections": ["@angular-eslint/schematics"],
"analytics": false
}
}
15 changes: 15 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Name of Stack for easier Portainer view
name: angular-web-task2

# 👉 CMD to run: docker compose up
services:
web:
image: "ghcr.io/amexei/angular-react-starter:lastest"
ports:
- "80:80"
command: nginx -g "daemon off;"
# 👉 CMD to run docker build image for first part of the task
# docker run -d -p 80:80 angular-web-task-web
# docker exec -it ❗container_id❗ /bin/sh
# curl localhost:80
# docker container stop ❗container_id❗
22 changes: 22 additions & 0 deletions nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# ❗ https://dev.to/oneofthedevs/docker-angular-nginx-37e4 used from here and followed this guide

server {
listen 80;
sendfile on;
default_type application/octet-stream;

gzip on;
gzip_http_version 1.1;
gzip_disable "MSIE [1-6]\.";
gzip_min_length 256;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
gzip_comp_level 9;

root /usr/share/nginx/html;

location / {
try_files $uri $uri/ /index.html =404;
}
}