github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/scripts/build.sh (about)

     1  #!/usr/bin/env bash
     2  set -e
     3  
     4  COZY_ENV_DFL=production
     5  
     6  [ -z "${COZY_ENV}" ] && COZY_ENV="${COZY_ENV_DFL}"
     7  [ -z "${COZY_DEPLOY_USER}" ] && COZY_DEPLOY_USER="${USER}"
     8  
     9  pushd "$(dirname "$0")" > /dev/null
    10  WORK_DIR=$(dirname "$(pwd)")
    11  popd > /dev/null
    12  
    13  if [ -r "${WORK_DIR}/local.env" ]; then
    14  	. "${WORK_DIR}/local.env"
    15  fi
    16  
    17  echo_err() {
    18  	>&2 echo -e "ERR: ${1}"
    19  }
    20  
    21  echo_wrn() {
    22  	>&2 echo -e "WRN: ${1}"
    23  }
    24  
    25  usage() {
    26  	echo -e "Usage: ${1} <release [target] | install | dev | assets | debug-assets | clean>"
    27  	echo -e "\nCommands:\n"
    28  	echo -e "  release [target]  Builds a release of the current working-tree."
    29  	echo -e "                    if specified, target is the path for generated binary"
    30  	echo -e "  install           Builds a release and install it the GOPATH"
    31  	echo -e "  dev               Builds a dev version"
    32  	echo -e "  assets            Move and download all the required assets"
    33  	echo -e "                    (see: ./assets/externals)"
    34  	echo -e "  debug-assets      Create a debug-assets/ directory with all the assets"
    35  	echo -e "  clean             Remove all generated files from the working-tree"
    36  
    37  	echo -e "\nEnvironment variables:"
    38  	echo -e "\n  COZY_ENV"
    39  	echo -e "    with release command, specify the environment of the release."
    40  	echo -e "    can be \"production\" or \"development\". default: \"${COZY_ENV_DFL}\""
    41  }
    42  
    43  # The version string is deterministic and reflects entirely the state
    44  # of the working-directory from which the release is built from. It is
    45  # generated using the following format:
    46  #
    47  # 		<TAG>[-<NUMBER OF COMMITS AFTER TAG>][-dirty][-dev]
    48  #
    49  # Where:
    50  #  - <TAG>: closest annotated tag of the current working directory. If
    51  #    no tag is present, is uses the string "v0". This is not allowed
    52  #    in a production release.
    53  #  - <NUMBER OF COMMITS AFTER TAG>: number of commits after the
    54  #    closest tag if the current working directory does not point
    55  #    exactly to a tag
    56  #  - -dirty: added if the working if the working-directory is not
    57  #    clean (contains un-commited modifications). This is not allowed
    58  #    in production release.
    59  #  - -dev: added for a development mode relase
    60  #
    61  # The outputed binary is named "cozy-stack-${VERSION_STRING}". A
    62  # SHA256 checksum of the binary is also generated in a file named
    63  # "cozy-stack-${VERSION_STRING}.sha256".
    64  do_release() {
    65  	#do_assets
    66  	do_build "$@"
    67  
    68  	openssl dgst -sha256 -hex "${BINARY}" > "${BINARY}.sha256"
    69  	printf "%s\t" "${BINARY}"
    70  	sed -E 's/SHA256\((.*)\)= ([a-f0-9]+)$/\2/g' < "${BINARY}.sha256"
    71  }
    72  
    73  do_install() {
    74  	check_env
    75  	do_prepare_ldflags
    76  
    77  	printf "installing cozy-stack in %s... " "$(go env GOPATH)/bin"
    78  	go install -ldflags "\
    79  		-X github.com/cozy/cozy-stack/pkg/config.Version=${VERSION_STRING} \
    80  		-X github.com/cozy/cozy-stack/pkg/config.BuildTime=${BUILD_TIME} \
    81  		-X github.com/cozy/cozy-stack/pkg/config.BuildMode=${BUILD_MODE}"
    82  	echo "ok"
    83  }
    84  
    85  do_build() {
    86  	check_env
    87  	do_prepare_ldflags
    88  
    89  	if [ -z "${1}" ]; then
    90  		BINARY="$(pwd)/cozy-stack-${VERSION_OS_ARCH}-${VERSION_STRING}"
    91  	else
    92  		BINARY="${1}"
    93  	fi
    94  
    95  	printf "building cozy-stack in %s... " "${BINARY}"
    96  	pushd "${WORK_DIR}" > /dev/null
    97  	go build -ldflags "\
    98  		-X github.com/cozy/cozy-stack/pkg/config.Version=${VERSION_STRING} \
    99  		-X github.com/cozy/cozy-stack/pkg/config.BuildTime=${BUILD_TIME} \
   100  		-X github.com/cozy/cozy-stack/pkg/config.BuildMode=${BUILD_MODE}" \
   101  		-o "${BINARY}"
   102  	popd > /dev/null
   103  	echo "ok"
   104  }
   105  
   106  do_prepare_ldflags() {
   107  	eval "$(go env)"
   108  
   109  	VERSION_OS_ARCH="${GOOS}-${GOARCH}"
   110  	if [ -z "${VERSION_STRING}" ]; then
   111  		VERSION_STRING=$(git -C "${WORK_DIR}" --work-tree="${WORK_DIR}" \
   112  			describe --tags --dirty 2> /dev/null)
   113  
   114  		if [ -z "${VERSION_STRING}" ]; then
   115  			VERSION_STRING="v0-$(git -C "${WORK_DIR}" rev-parse --short HEAD)"
   116  			echo_wrn "No tag has been found to version the stack, using \"${VERSION_STRING}\" as version number"
   117  		fi
   118  
   119  		if ! git -C "${WORK_DIR}" diff --exit-code HEAD &>/dev/null; then
   120  			if [ "${COZY_ENV}" == "production" ]; then
   121  				echo_err "Can not build a production release in a dirty work-tree"
   122  				exit 1
   123  			fi
   124  			VERSION_STRING="${VERSION_STRING}-dirty"
   125  		fi
   126  
   127  		if [ "${COZY_ENV}" == "development" ]; then
   128  			VERSION_STRING="${VERSION_STRING}-dev"
   129  		fi
   130  	fi
   131  
   132  	BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
   133  	BUILD_MODE="${COZY_ENV}"
   134  }
   135  
   136  do_assets() {
   137  	printf "executing go generate...\n"
   138  	go install github.com/cozy/cozy-stack/pkg/statik
   139  	pushd "${WORK_DIR}" > /dev/null
   140  	go generate ./web
   141  	popd > /dev/null
   142  	echo "ok"
   143  }
   144  
   145  do_debug_assets() {
   146  	assets_dst="${WORK_DIR}/debug-assets"
   147  	rm -rf "${assets_dst}"
   148  	mkdir -p "${assets_dst}/css" "${assets_dst}/js"
   149  	pushd "$WORK_DIR" > /dev/null
   150  	for i in assets/* ; do
   151  		ln -s "${WORK_DIR}/${i}" "debug-${i}"
   152  	done
   153  	asset_name=""
   154  	asset_url=""
   155  	asset_sha=""
   156  	while IFS= read -r line; do
   157  		if [ "${line:0:1}" = "#" ]; then continue; fi
   158  		if [ -z "${line}" ]; then continue; fi
   159  		IFS=" " read -r -a line_split <<< "${line}"
   160  		case "${line_split[0]}" in
   161  			name)
   162  				asset_name="${line_split[1]}"
   163  				;;
   164  			url)
   165  				asset_url="${line_split[1]}"
   166  				;;
   167  			sha256)
   168  				asset_sha="${line_split[1]}"
   169  				download_debug_asset "${asset_name}" "${asset_url}" "${asset_sha}"
   170  				asset_name=""
   171  				asset_url=""
   172  				asset_sha=""
   173  				;;
   174  			*)
   175  				echo_err "Failed to parse assets/.externals file"
   176  				echo_err "Unknown field named \"${line_split[0]}\""
   177  				exit 1
   178  				;;
   179  			esac
   180  	done < "assets/.externals"
   181  	popd > /dev/null
   182  	echo 'You can now run `go run . serve --assets ./debug-assets` to debug the assets'
   183  }
   184  
   185  download_debug_asset() {
   186  	printf "downloading %s: " "${1}"
   187  	if ! curl -sSL --fail "${2}" 1> "${assets_dst}/${1}" 2>/dev/null; then
   188  		echo "failed"
   189  		echo_err "Could not fetch resource with curl: ${2}"
   190  		exit 1
   191  	fi
   192  	if [ -n "${3}" ]; then
   193  		dgst=$(openssl dgst -sha256 < "${assets_dst}/${1}" | sed 's/^.* //')
   194  		if [ "${3}" != "${dgst}" ]; then
   195  			echo "failed"
   196  			echo_err "Checksum SHA256 does not match for asset ${1} downloaded on ${2}:"
   197  			echo_err "  expecting \"${3}\", got \"${dgst}\"."
   198  			exit 1
   199  		fi
   200  	fi
   201  	echo "ok"
   202  }
   203  
   204  do_clean() {
   205  	find . -name "cozy-stack-*" -print -delete
   206  }
   207  
   208  check_env() {
   209  	if [ "${COZY_ENV}" != "production" ] && [ "${COZY_ENV}" != "development" ]; then
   210  		echo_err "ERR: COZY_ENV should either be production or development"
   211  		exit 1
   212  	fi
   213  }
   214  
   215  case "${1}" in
   216  	release)
   217  		shift
   218  		do_release "$@"
   219  		;;
   220  
   221  	install)
   222  		do_install
   223  		;;
   224  
   225  	clean)
   226  		do_clean
   227  		;;
   228  
   229  	assets)
   230  		do_assets
   231  		;;
   232  
   233  	debug-assets)
   234  		do_debug_assets
   235  		;;
   236  
   237  	dev)
   238  		COZY_ENV=development do_build cozy-stack
   239  		;;
   240  
   241  	*)
   242  		usage "${0}"
   243  		exit 1
   244  esac
   245  
   246  exit 0