diff --git a/automation/build.sh b/automation/build.sh index 8cfe7fd4..121138f1 100755 --- a/automation/build.sh +++ b/automation/build.sh @@ -9,7 +9,6 @@ # * TAG: The default will be the current branch name # * PUSH_IMAGES # * CLEANUP -# * MIXPANEL_TOKEN: default key to inject in the supervisor image # * EXTRA_TAG: when PUSH_IMAGES is true, additional tag to push to the registries # # Builds the supervisor for the architecture defined by $ARCH. @@ -45,12 +44,12 @@ if ! [ -x "$(command -v npx)" ]; then exit 1 fi +PROJECT_NAME="${PROJECT_NAME:-${ARCH}-supervisor}" +SERVICE_NAME="${SERVICE_NAME:-main}" + # This is the supervisor image we will produce TARGET_IMAGE=balena/$ARCH-supervisor:$TAG -TARGET_BUILD_IMAGE=balena/$ARCH-supervisor:$TAG-build - MASTER_IMAGE=balena/$ARCH-supervisor:master -MASTER_BUILD_IMAGE=balena/$ARCH-supervisor:master-build CACHE_FROM="" function useCache() { @@ -88,25 +87,50 @@ function processDockerfile() { fi } +function deviceType() { + case ${ARCH} in + aarch64) + echo "raspberrypi4-64" + ;; + armv7hf) + echo "raspberrypi3" + ;; + rpi) + echo "raspberry-pi" + ;; + i386) + echo "qemux86" + ;; + amd64) + echo "intel-nuc" + ;; + *) + echo "unrecognized architecture ${ARCH}" + exit 1 + ;; + esac +} + export ARCH useCache "${TARGET_IMAGE}" -useCache "${TARGET_BUILD_IMAGE}" useCache "${MASTER_IMAGE}" -useCache "${MASTER_BUILD_IMAGE}" # Wait for our cache to be downloaded wait -BUILD_ARGS="$CACHE_FROM --build-arg ARCH=${ARCH}" -# Try to build the first stage -processDockerfile | docker build -f - -t "${TARGET_BUILD_IMAGE}" --target BUILD ${BUILD_ARGS} . +BUILD_ARGS="$CACHE_FROM --buildArg ARCH=$ARCH" -# Now try to build the final stage -processDockerfile | docker build -f - -t "${TARGET_IMAGE}" ${BUILD_ARGS} . +# Make a copy of the file to match the architecture +processDockerfile > Dockerfile.${ARCH} + +# Build the image +balena build --deviceType $(deviceType) --arch ${ARCH} --dockerfile ./Dockerfile.${ARCH} \ + --projectName ${PROJECT_NAME} --tag ${TAG} ${BUILD_ARGS} if [ "${PUSH_IMAGES}" == "true" ]; then - retryImagePush "${TARGET_BUILD_IMAGE}" & + # Tag the CLI generated image with the target + docker tag "${PROJECT_NAME}_${SERVICE_NAME}:${TAG}" ${TARGET_IMAGE} retryImagePush "${TARGET_IMAGE}" & if [ -n "${EXTRA_TAG}" ]; then @@ -121,7 +145,6 @@ wait if [ "$CLEANUP" = "true" ]; then docker rmi \ "${TARGET_IMAGE}" \ - "${TARGET_BUILD_IMAGE}" \ - "${MASTER_IMAGE}" \ - "${MASTER_BUILD_IMAGE}" + "${MASTER_IMAGE}" fi + diff --git a/circle.yml b/circle.yml index c8f05cb2..0c9b445e 100644 --- a/circle.yml +++ b/circle.yml @@ -8,7 +8,7 @@ defaults: &defaults version: 18.09.3 docker_layer_caching: true - run: - name: Check docker is running and install git + name: Check docker is running and install dependencies command: | docker info apk update && apk upgrade && apk add --no-cache \ @@ -19,9 +19,15 @@ defaults: &defaults nodejs \ nodejs-npm \ openssh-client + - run: + name: Install balena CLI and test it + command: | + apk add --no-cache curl python3 g++ linux-headers && \ + npm install balena-cli -g --production --unsafe-perm && \ + balena version -v - checkout - run: - name: Initialize the submodules (yocto layers) + name: Initialize the submodules command: | git submodule update --init --recursive git clean -fxd base-image @@ -43,15 +49,41 @@ defaults: &defaults else export PUSH_IMAGES=false fi - # start the build for this architecture + if [ "$PRODUCTION_API_TOKEN" != "" ]; then + balena login --token $PRODUCTION_API_TOKEN + export DEPLOY_TO_PRODUCTION=${DEPLOY_TO_PRODUCTION} + else + export DEPLOY_TO_PRODUCTION=false + fi + if [ "$STAGING_API_TOKEN" != "" ]; then + export DEPLOY_TO_PRODUCTION=${DEPLOY_TO_STAGING} + else + export DEPLOY_TO_STAGING=false + fi + # Create required env vars export TAG=$(echo ${CIRCLE_BRANCH} | sed 's/[^a-z0-9A-Z_.-]/-/g') export ARCH=${ARCH} - bash automation/build.sh - if [ "${CIRCLE_BRANCH}" = "master" ] && [ "${DEPLOY_TO_BALENA}" = "true" ]; then + export PROJECT_NAME=${ARCH}-supervisor + export SERVICE_NAME=main + # start the build for this architecture + bash -x automation/build.sh + if [ "${CIRCLE_BRANCH}" = "master" ] && [ "${DEPLOY_TO_STAGING}" = "true" ]; then echo "Deploying to balena API (staging)" - ARCH=${ARCH} TAG=$VERSION_TAG API_KEY=$STAGING_API_KEY API_ENDPOINT=$STAGING_API_ENDPOINT node automation/deploy-to-balena-cloud.js + BALENARC_BALENA_URL=$STAGING_API_ENDPOINT balena login --token $STAGING_API_TOKEN + BALENARC_BALENA_URL=$STAGING_API_ENDPOINT balena deploy ${BALENA_OS_ORG}/${PROJECT_NAME} \ + --projectName ${PROJECT_NAME} --tag ${TAG} \ + --release-tag gh_branch ${TAG} version ${VERSION_TAG} + # Cleanup credentials just in case + rm ~/.balena/token + fi + if [ "${CIRCLE_BRANCH}" = "master" ] && [ "${DEPLOY_TO_PRODUCTION}" = "true" ]; then echo "Deploying to balena API (production)" - ARCH=${ARCH} TAG=$VERSION_TAG API_KEY=$PRODUCTION_API_KEY API_ENDPOINT=$PRODUCTION_API_ENDPOINT node automation/deploy-to-balena-cloud.js + BALENARC_BALENA_URL=$PRODUCTION_API_ENDPOINT balena login --token $PRODUCTION_API_TOKEN + BALENARC_BALENA_URL=$PRODUCTION_API_ENDPOINT balena deploy ${BALENA_OS_ORG}/${PROJECT_NAME} \ + --projectName ${PROJECT_NAME} --tag ${TAG} \ + --release-tag gh_branch ${TAG} version ${VERSION_TAG} + # Cleanup credentials just in case + rm ~/.balena/token fi version: 2 @@ -74,8 +106,8 @@ jobs: DOCKER_USERNAME: travisciresin ARCH: amd64 PUSH_IMAGES: 'true' - STAGING_API_ENDPOINT: https://api.balena-staging.com - PRODUCTION_API_ENDPOINT: https://api.balena-cloud.com + STAGING_API_ENDPOINT: balena-staging.com + PRODUCTION_API_ENDPOINT: balena-cloud.com DEBUG: '' amd64: <<: *defaults @@ -83,8 +115,11 @@ jobs: DOCKER_USERNAME: travisciresin ARCH: amd64 PUSH_IMAGES: 'true' - STAGING_API_ENDPOINT: https://api.balena-staging.com - PRODUCTION_API_ENDPOINT: https://api.balena-cloud.com + STAGING_API_ENDPOINT: balena-staging.com + PRODUCTION_API_ENDPOINT: balena-cloud.com + DEPLOY_TO_PRODUCTION: 'false' + DEPLOY_TO_STAGING: 'false' + BALENA_OS_ORG: 'balena_os' DEBUG: '' i386: <<: *defaults @@ -92,8 +127,11 @@ jobs: DOCKER_USERNAME: travisciresin ARCH: i386 PUSH_IMAGES: 'true' - STAGING_API_ENDPOINT: https://api.balena-staging.com - PRODUCTION_API_ENDPOINT: https://api.balena-cloud.com + STAGING_API_ENDPOINT: balena-staging.com + PRODUCTION_API_ENDPOINT: balena-cloud.com + DEPLOY_TO_PRODUCTION: 'false' + DEPLOY_TO_STAGING: 'false' + BALENA_OS_ORG: 'balena_os' DEBUG: '' armv7hf: <<: *defaults @@ -101,8 +139,11 @@ jobs: DOCKER_USERNAME: travisciresin ARCH: armv7hf PUSH_IMAGES: 'true' - STAGING_API_ENDPOINT: https://api.balena-staging.com - PRODUCTION_API_ENDPOINT: https://api.balena-cloud.com + STAGING_API_ENDPOINT: balena-staging.com + PRODUCTION_API_ENDPOINT: balena-cloud.com + DEPLOY_TO_PRODUCTION: 'false' + DEPLOY_TO_STAGING: 'false' + BALENA_OS_ORG: 'balena_os' DEBUG: '' aarch64: <<: *defaults @@ -110,8 +151,11 @@ jobs: DOCKER_USERNAME: travisciresin ARCH: aarch64 PUSH_IMAGES: 'true' - STAGING_API_ENDPOINT: https://api.balena-staging.com - PRODUCTION_API_ENDPOINT: https://api.balena-cloud.com + STAGING_API_ENDPOINT: balena-staging.com + PRODUCTION_API_ENDPOINT: balena-cloud.com + DEPLOY_TO_PRODUCTION: 'false' + DEPLOY_TO_STAGING: 'false' + BALENA_OS_ORG: 'balena_os' DEBUG: '' rpi: <<: *defaults @@ -119,8 +163,11 @@ jobs: DOCKER_USERNAME: travisciresin ARCH: rpi PUSH_IMAGES: 'true' - STAGING_API_ENDPOINT: https://api.balena-staging.com - PRODUCTION_API_ENDPOINT: https://api.balena-cloud.com + STAGING_API_ENDPOINT: balena-staging.com + PRODUCTION_API_ENDPOINT: balena-cloud.com + DEPLOY_TO_PRODUCTION: 'false' + DEPLOY_TO_STAGING: 'false' + BALENA_OS_ORG: 'balena_os' DEBUG: '' workflows: