mirror of
https://github.com/Cronocide/fitbit-web-ui-app.git
synced 2025-01-22 11:29:03 +00:00
Added build files
This commit is contained in:
parent
b670002668
commit
9ca93b5bb2
8
Dockerfile
Normal file
8
Dockerfile
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# This version of Numpy requires python 3.10
|
||||||
|
FROM python:3.10 AS python
|
||||||
|
ENV PROJ_NAME=fitbit-web-ui-app
|
||||||
|
ADD ./requirements.txt /requirements.txt
|
||||||
|
RUN pip3 install -r /requirements.txt
|
||||||
|
ADD ./ /$PROJ_NAME
|
||||||
|
WORKDIR /$PROJ_NAME
|
||||||
|
CMD gunicorn --chdir src app:server --bind 0.0.0.0:80
|
79
Jenkinsfile
vendored
Normal file
79
Jenkinsfile
vendored
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#!/usr/bin/env groovy
|
||||||
|
|
||||||
|
pipeline {
|
||||||
|
agent {
|
||||||
|
label 'nomad'
|
||||||
|
}
|
||||||
|
parameters {
|
||||||
|
string(name: 'GIT_REPO_NAME', defaultValue: 'git.cronocide.net', description: 'The hostname of the git repository.')
|
||||||
|
string(name: 'USERN', defaultValue: 'cronocide', description: 'The username of the user in the git repository.')
|
||||||
|
booleanParam(name: 'PREPARE', defaultValue: true, description: 'Do preparations on this project.')
|
||||||
|
booleanParam(name: 'INSPECT', defaultValue: false, description: 'Do inspections on this project.')
|
||||||
|
booleanParam(name: 'BUILD', defaultValue: true, description: 'Do builds on this project.')
|
||||||
|
booleanParam(name: 'TEST', defaultValue: true, description: 'Do tests on this project.')
|
||||||
|
booleanParam(name: 'PUBLISH', defaultValue: true, description: 'Publish this project.')
|
||||||
|
booleanParam(name: 'DEPLOY', defaultValue: false, description: 'Deploy this project.')
|
||||||
|
}
|
||||||
|
environment {
|
||||||
|
WORKSPACE_PATH = "/opt/nomad/alloc/${NOMAD_ALLOC_ID}/${NOMAD_TASK_NAME}${WORKSPACE}"
|
||||||
|
DESCRIPTION = "Fitbit Wellness Report WebUI"
|
||||||
|
}
|
||||||
|
stages {
|
||||||
|
stage('Prepare') {
|
||||||
|
when { expression { params.PREPARE } }
|
||||||
|
steps {
|
||||||
|
withEnv(['ACTION=cicd_prepare']) {
|
||||||
|
sh ( script: './build.sh')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Inspect') {
|
||||||
|
when { expression { params.INSPECT } }
|
||||||
|
steps {
|
||||||
|
withEnv(['ACTION=cicd_inspect']) {
|
||||||
|
sh ( script: './build.sh')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Build') {
|
||||||
|
when { expression { params.BUILD } }
|
||||||
|
steps {
|
||||||
|
withEnv(['ACTION=cicd_build']) {
|
||||||
|
sh ( script: './build.sh')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Test') {
|
||||||
|
when { expression { params.TEST } }
|
||||||
|
steps {
|
||||||
|
withEnv(['ACTION=cicd_test']) {
|
||||||
|
sh ( script: './build.sh')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Publish') {
|
||||||
|
when { expression { params.PUBLISH } }
|
||||||
|
steps {
|
||||||
|
withEnv(['ACTION=cicd_publish']) {
|
||||||
|
sh ( script: './build.sh')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Deploy') {
|
||||||
|
when { expression { params.DEPLOY } }
|
||||||
|
steps {
|
||||||
|
withEnv(['ACTION=cicd_deploy']) {
|
||||||
|
sh ( script: './build.sh')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
post {
|
||||||
|
success {
|
||||||
|
echo 'Pipeline succeeded.'
|
||||||
|
}
|
||||||
|
failure {
|
||||||
|
echo 'Pipeline failed.'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
207
build.sh
Executable file
207
build.sh
Executable file
@ -0,0 +1,207 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Generic Build Script for Jenkins
|
||||||
|
# v1.0 Mar 2023 by Cronocide
|
||||||
|
|
||||||
|
# ___ ___ ___ _ ___ ___ ___ _ _ _____ ___
|
||||||
|
# | _ )/ _ \_ _| | | __| _ \ _ \ | /_\_ _| __|
|
||||||
|
# | _ \ (_) | || |__| _|| / _/ |__ / _ \| | | _|
|
||||||
|
# |___/\___/___|____|___|_|_\_| |____/_/ \_\_| |___|
|
||||||
|
|
||||||
|
# Get the OS type. Most specific distributions first.
|
||||||
|
export OS="$(uname -a)"
|
||||||
|
[[ "$OS" == *"iPhone"* || "$OS" == *"iPad"* ]] && export OS="iOS"
|
||||||
|
[[ "$OS" == *"ndroid"* ]] && export OS="Android"
|
||||||
|
[[ "$OS" == *"indows"* ]] && export OS="Windows"
|
||||||
|
[[ "$OS" == *"arwin"* ]] && export OS="macOS"
|
||||||
|
[[ "$OS" == *"BSD"* ]] && export OS="BSD"
|
||||||
|
[[ "$OS" == *"inux"* ]] && export OS="Linux"
|
||||||
|
|
||||||
|
# Verify a list of software or operating systems. Inverted returns for ease-of-use.
|
||||||
|
__missing_os() {
|
||||||
|
for i in $(echo "$@"); do
|
||||||
|
! __no_os "$i" && return 1
|
||||||
|
done
|
||||||
|
echo "This function is not available on $OS." && return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
__no_os() {
|
||||||
|
[[ "$OS" == "$1" ]] && return 1
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Verify we have dependencies needed to execute successfully
|
||||||
|
__missing_reqs() {
|
||||||
|
for i in "$@"; do
|
||||||
|
[[ "$0" != "$i" ]] && __no_req "$i" && echo "$i is required to perform this function." && return 0
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
__no_req() {
|
||||||
|
[[ "$(type $1 2>/dev/null)" == '' ]] && return 0
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# An abstraction for curl/wget. Accepts url and <optional output path>
|
||||||
|
__http_get() {
|
||||||
|
OUTPUT="$2"; [ -z "$OUTPUT" ] && export OUTPUT="-"
|
||||||
|
if [[ "$(type curl 2>/dev/null)" != '' ]]; then
|
||||||
|
curl -s "$1" -o "$OUTPUT"
|
||||||
|
[ "$OUTPUT" != "-" ] && (! [ -f "$OUTPUT" ] || [[ $(cat "$OUTPUT" | tr -d '\0' 2>/dev/null) == '' ]]) && return 1
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
if ! [[ "$(type wget 2>/dev/null)" != '' ]]; then
|
||||||
|
wget "$1" -O "$2"
|
||||||
|
[ "$OUTPUT" != "-" ] && (! [ -f "$2" ] || [[ $(cat "$2" | tr -d '\0' 2>/dev/null) == '' ]]) && return 1
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo "curl or wget is required to perform this function." && return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
__missing_sed() {
|
||||||
|
__no_req "sed" && __no_req "gsed" && echo "sed or gsed is required to perform this function." && return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
sed_i() {
|
||||||
|
__missing_sed && return 1;
|
||||||
|
if [[ "$OS" == "macOS" ]]; then
|
||||||
|
if [[ $(type gsed 2>/dev/null) != '' ]]; then
|
||||||
|
gsed -i "$@";
|
||||||
|
else
|
||||||
|
sed -i '' "$@";
|
||||||
|
fi;
|
||||||
|
else
|
||||||
|
sed -i "$@";
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Echo errors to stderr
|
||||||
|
error() {
|
||||||
|
echo "$@" 1>&2
|
||||||
|
}
|
||||||
|
|
||||||
|
# Provide a reliable ISO 8601 timestamp.
|
||||||
|
isotime() {
|
||||||
|
[[ "$OS" == "Linux" ]] && echo $(date --iso-8601=seconds) && return 0
|
||||||
|
echo $(date +"%Y-%m-%dT%H:%M:%S%z" | sed 's#\(-[0-9]\{2\}\)00#\1:00#')
|
||||||
|
}
|
||||||
|
|
||||||
|
# ___ _ _ _ _ ___ _____ ___ ___ _ _ ___
|
||||||
|
# | __| | | | \| |/ __|_ _|_ _/ _ \| \| / __|
|
||||||
|
# | _|| |_| | .` | (__ | | | | (_) | .` \__ \
|
||||||
|
# |_| \___/|_|\_|\___| |_| |___\___/|_|\_|___/
|
||||||
|
|
||||||
|
|
||||||
|
cicd_prepare() {
|
||||||
|
# Prepare the build environment.
|
||||||
|
echo "Preparing for Build"
|
||||||
|
# TODO
|
||||||
|
echo "Completed Preparing for Build"
|
||||||
|
}
|
||||||
|
|
||||||
|
cicd_inspect() {
|
||||||
|
# Information about the build environment.
|
||||||
|
echo "Inspecting Build Environment"
|
||||||
|
env
|
||||||
|
echo "Completed Inspecting Build Environment"
|
||||||
|
}
|
||||||
|
|
||||||
|
cicd_build() {
|
||||||
|
# Build a new software artifact.
|
||||||
|
__missing_reqs "docker" && exit 1
|
||||||
|
echo "Building Software"
|
||||||
|
docker build --pull=true \
|
||||||
|
--label "org.opencontainers.image.vendor=cronocide.net" \
|
||||||
|
--label "org.opencontainers.image.title=${PROJECT_NAME}" \
|
||||||
|
--label "org.opencontainers.image.url=https://${GIT_REPO_NAME}" \
|
||||||
|
--label "org.opencontainers.image.source=https://${IMAGE_NAME}" \
|
||||||
|
--label "net.cronocide.build-info.git-repo=${GIT_URL}" \
|
||||||
|
--label "net.cronocide.build-info.git-branch=${GIT_BRANCH}" \
|
||||||
|
--label "net.cronocide.build-info.git-commit=${GIT_COMMIT}" \
|
||||||
|
--label "net.cronocide.build-info.build-time=$(isotime)" \
|
||||||
|
--tag="$COMMIT_TAG" \
|
||||||
|
--tag="$LATEST_TAG" \
|
||||||
|
.
|
||||||
|
echo "Completed Building Software"
|
||||||
|
}
|
||||||
|
|
||||||
|
cicd_test() {
|
||||||
|
# Run tests on the built software artifact.
|
||||||
|
echo "Testing Software"
|
||||||
|
# TODO
|
||||||
|
echo "Completed Testing Software"
|
||||||
|
}
|
||||||
|
|
||||||
|
cicd_publish() {
|
||||||
|
# Publish the software to artifact repositories.
|
||||||
|
__missing_reqs "docker" && exit 1
|
||||||
|
echo "Publishing Software"
|
||||||
|
# TODO: Improve the logic of this Docker login flow.
|
||||||
|
LOGIN_CREDS="DOCKER_USERNAME DOCKER_PASSWORD"
|
||||||
|
for CRED in $(echo "$LOGIN_CREDS"); do
|
||||||
|
[ -z "${!CRED}" ] && echo "Missing $CRED, skipping docker login." && export SKIP_DOCKER_LOGIN=1
|
||||||
|
done
|
||||||
|
[[ "$SKIP_DOCKER_LOGIN" != "1" ]] && docker login "$GIT_REPO_NAME" -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"
|
||||||
|
docker push ${COMMIT_TAG}
|
||||||
|
docker push ${LATEST_TAG}
|
||||||
|
echo "Completed Publishing Software"
|
||||||
|
}
|
||||||
|
|
||||||
|
cicd_deploy() {
|
||||||
|
echo "Deploying Software"
|
||||||
|
# TODO: Check for a nomad folder
|
||||||
|
if ! [ -f "$PROJECT_NAME".hcl ]; then
|
||||||
|
__http_get "https://setup.cronocide.com/nomad/base.hcl" "$PROJECT_NAME".hcl
|
||||||
|
__http_get "https://setup.cronocide.com/nomad/base.volume" "$PROJECT_NAME".volume
|
||||||
|
sed_i "s#base#$PROJECT_NAME#g" "$PROJECT_NAME".hcl
|
||||||
|
sed_i "s#image:latest#$PROJECT_NAME:latest#g" "$PROJECT_NAME".hcl
|
||||||
|
sed_i "s#base#$PROJECT_NAME#g" "$PROJECT_NAME".volume
|
||||||
|
nomad volume create "$PROJECT_NAME".volume
|
||||||
|
else
|
||||||
|
nomad job run "$PROJECT_NAME".hcl
|
||||||
|
fi
|
||||||
|
echo "Completed Deploying Software"
|
||||||
|
}
|
||||||
|
|
||||||
|
prepare_devenv() {
|
||||||
|
# Place actions here to prepare the environment for development
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# __ __ _ ___ _ _
|
||||||
|
# | \/ | /_\ |_ _| \| |
|
||||||
|
# | |\/| |/ _ \ | || .` |
|
||||||
|
# |_| |_/_/ \_\___|_|\_|
|
||||||
|
|
||||||
|
__missing_reqs "git sed" && exit 1
|
||||||
|
|
||||||
|
# Verify that an ACTION is supplied in the environment.
|
||||||
|
BUILD_PREFIX="cicd"
|
||||||
|
[ -z "$ACTION" ] && error "No ACTION supplied, no action taken." && exit 1
|
||||||
|
[[ "$ACTION" != "$BUILD_PREFIX"* ]] && error "Action $ACTION is not recognized as a valid action."
|
||||||
|
__no_req "$ACTION" && error "Action $ACTION is not recognized as a valid action." && exit 1
|
||||||
|
|
||||||
|
# Fill in variables if not supplied by CICD
|
||||||
|
[ -z "$USERN" ] && export USERN=cronocide
|
||||||
|
[ -z "$GIT_REPO_NAME" ] && export GIT_REPO_NAME=git.cronocide.net
|
||||||
|
|
||||||
|
# Update submodules if the build system did not
|
||||||
|
git submodule update --init --recursive
|
||||||
|
|
||||||
|
# Prepare build system
|
||||||
|
prepare_devenv
|
||||||
|
|
||||||
|
# Define needed build strings
|
||||||
|
DIR=$(cd $(dirname $BASH_SOURCE[0]) && pwd)
|
||||||
|
PROJECT_NAME="$(git config --local remote.origin.url|sed -n 's#.*/\([^/.]*\)\(\.git\)\{0,1\}$#\1#p')"
|
||||||
|
IMAGE_NAME=$(echo "$GIT_REPO_NAME/$USERN/$PROJECT_NAME" | tr "[:upper:]" "[:lower:]")
|
||||||
|
GIT_COMMIT=$(git rev-parse HEAD)
|
||||||
|
GIT_COMMITTER=$(git log -1 --pretty=format:'%ae')
|
||||||
|
GIT_URL=$(git config --get remote.origin.url)
|
||||||
|
GIT_BRANCH=$(git branch | grep \* | cut -d ' ' -f2)
|
||||||
|
COMMIT_TAG="${IMAGE_NAME}:${GIT_COMMIT}"
|
||||||
|
LATEST_TAG="${IMAGE_NAME}:latest"
|
||||||
|
|
||||||
|
# Run specified build task
|
||||||
|
"$ACTION"
|
Loading…
Reference in New Issue
Block a user