-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce
mix build
task to update/replace an old...
...the release.sh script. We have added a few more checks: repo is clean, tests are passing. We prompt user with a few reminders (instead of simple "warning"-like text output). Furthermore, we re-wrote the `build.sh` and made it cleaner (we hope so, at least).
- Loading branch information
Showing
4 changed files
with
126 additions
and
86 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,71 +1,108 @@ | ||
#!/bin/bash | ||
# | ||
# Defines Docker build process for production ready image of our Elixir app. | ||
# | ||
# We want to define Elixir/Erlang versions in minimum places to improve maintainability, | ||
# so we use `.env` file and parse it to convert to build arguments list. | ||
# | ||
# Example: | ||
# | ||
# $ ./scripts/build.sh lexin 0.3.0 | ||
# $ ./scripts/build.sh lexin 0.3.0 --force | ||
# $ ./scripts/build.sh lexin 0.3.0 --force --no-cache | ||
# | ||
# Note: `--no-cache` should always be used only with `--force` going first; `--no-cache` tells | ||
# Docker to skip local cache. | ||
#!/usr/bin/env bash | ||
|
||
if ! docker version > /dev/null 2>&1; then | ||
echo "Docker is not running. We cannot build release without Docker!" | ||
# Strict mode for better error handling | ||
set -euo pipefail | ||
|
||
usage() { | ||
echo "Usage: $0 IMAGE_TAG [OPTIONS]" | ||
echo "" | ||
echo "Build and push a Docker image for an Elixir application" | ||
echo "" | ||
echo "Arguments:" | ||
echo "" | ||
echo " IMAGE_TAG Full image tag (e.g., ghcr.io/cr0t/lexin:0.3.0)" | ||
echo "" | ||
echo "Options:" | ||
echo "" | ||
echo " --force Force rebuild, removing existing image" | ||
echo " --no-cache Disable Docker build cache" | ||
echo "" | ||
echo "Examples:" | ||
echo "" | ||
echo " $0 ghcr.io/cr0t/lexin:0.3.0" | ||
echo " $0 ghcr.io/cr0t/lexin:0.3.0 --force" | ||
echo " $0 ghcr.io/cr0t/lexin:0.3.0 --force --no-cache" | ||
exit 1 | ||
fi | ||
} | ||
|
||
# We expect at least two arguments: application name and version number | ||
if [[ $# -lt 2 ]]; then | ||
echo "Please, provide application name and version number, for example:" | ||
echo "$0 my_app 1.1.0" | ||
exit 2 | ||
fi | ||
check_docker() { | ||
if ! command -v docker &> /dev/null; then | ||
echo "Error: Docker is not installed." >&2 | ||
exit 1 | ||
fi | ||
|
||
# But in addition we can also accept --force and --no-cache as third and fourth arguments | ||
if [ -n "$3" ] && [[ $3 == "--force" ]]; then | ||
FORCE_FLAG=true | ||
else | ||
FORCE_FLAG=false | ||
fi | ||
if ! docker info &> /dev/null; then | ||
echo "Error: Docker daemon is not running." >&2 | ||
exit 1 | ||
fi | ||
} | ||
|
||
if [ -n "$4" ] && [[ $4 == "--no-cache" ]]; then | ||
NO_CACHE_FLAG=true | ||
else | ||
parse_arguments() { | ||
FORCE_FLAG=false | ||
NO_CACHE_FLAG=false | ||
fi | ||
|
||
# Some information we will need to name and tag the image we're building | ||
APP_NAME=$1 | ||
APP_VERSION=$2 | ||
IMAGE_NAME="ghcr.io/cr0t/$APP_NAME:$APP_VERSION" | ||
EXISTING_IMAGE_ID=$(docker images -q $IMAGE_NAME 2> /dev/null) | ||
# Validate at least one argument | ||
[[ $# -lt 1 ]] && usage | ||
|
||
# Parse arguments | ||
while [[ $# -gt 0 ]]; do | ||
case "$1" in | ||
--force) | ||
FORCE_FLAG=true | ||
shift | ||
;; | ||
--no-cache) | ||
NO_CACHE_FLAG=true | ||
shift | ||
;; | ||
-*) | ||
echo "Error: Unknown option $1" >&2 | ||
usage | ||
;; | ||
*) | ||
if [[ -z "${IMAGE_NAME:-}" ]]; then | ||
IMAGE_NAME="$1" | ||
shift | ||
else | ||
echo "Error: Too many arguments" >&2 | ||
usage | ||
fi | ||
;; | ||
esac | ||
done | ||
} | ||
|
||
build_docker_image() { | ||
# Check if image exists and handle force rebuild | ||
local existing_image_id | ||
existing_image_id=$(docker images -q "$IMAGE_NAME" 2> /dev/null || true) | ||
|
||
if [[ -n "$existing_image_id" ]]; then | ||
if [[ "$FORCE_FLAG" == "true" ]]; then | ||
echo "Removing existing image $IMAGE_NAME" | ||
docker image rm "$existing_image_id" | ||
else | ||
echo "Image $IMAGE_NAME already exists. Use --force to rebuild." | ||
exit 3 | ||
fi | ||
fi | ||
|
||
readonly BUILD_PLATFORM="linux/amd64" | ||
readonly BUILD_ENV_ARGS=$(awk '!/^($|#)/ {printf "--build-arg %s ", $0}' .env) | ||
|
||
if [ -n "$EXISTING_IMAGE_ID" ] && ! $FORCE_FLAG; then | ||
echo "The image $IMAGE_NAME already exists: $EXISTING_IMAGE_ID!" | ||
echo "You can use --force to delete and rebuild it forcefully, or bump the version in mix.exs." | ||
echo "Note: add --no-cache to tell Docker skip local cache." | ||
exit 3 | ||
fi | ||
local build_flags="$BUILD_ENV_ARGS --platform $BUILD_PLATFORM --file .docker/Dockerfile.build" | ||
|
||
BUILD_PLATFORM="linux/amd64" | ||
BUILD_ENV_ARGS=$(for i in `cat .env | grep -v '#'`; do out+="--build-arg $i "; done; echo $out; out="") | ||
BUILD_FLAGS="$BUILD_ENV_ARGS --platform $BUILD_PLATFORM --file .docker/Dockerfile.build " | ||
[[ "$NO_CACHE_FLAG" == "true" ]] && build_flags="${build_flags} --no-cache" | ||
|
||
if $FORCE_FLAG && [ -n "$EXISTING_IMAGE_ID" ]; then | ||
docker image rm $EXISTING_IMAGE_ID | ||
fi | ||
# Execute build | ||
docker build --debug $build_flags --tag "$IMAGE_NAME" . | ||
} | ||
|
||
# NOTE: add `--progress plain` to simplify debugging | ||
if $NO_CACHE_FLAG; then | ||
docker build $BUILD_FLAGS --no-cache --tag $IMAGE_NAME . | ||
else | ||
docker build $BUILD_FLAGS --tag $IMAGE_NAME . | ||
fi | ||
main() { | ||
check_docker | ||
parse_arguments "$@" | ||
build_docker_image | ||
# docker push "$IMAGE_NAME" | ||
} | ||
|
||
# push it to GitHub | ||
docker push $IMAGE_NAME | ||
main "$@" |
This file was deleted.
Oops, something went wrong.