diff --git a/.encrypted.zip.enc b/.encrypted.zip.enc deleted file mode 100644 index 18da634..0000000 Binary files a/.encrypted.zip.enc and /dev/null differ diff --git a/.github/workflows/bundle.yml b/.github/workflows/bundle.yml new file mode 100644 index 0000000..05a844b --- /dev/null +++ b/.github/workflows/bundle.yml @@ -0,0 +1,178 @@ +name: Bundle + +on: + push: # Choose the branch that matches the Smalltalk version below + branches: + - squeak-trunk + # - squeak-5.3 + # - squeak-5.2 + paths-ignore: + - '**.md' # Skip changes in documentation artifacts + pull_request: # Choose the branch that matches the Smalltalk version below + branches: + - squeak-trunk + # - squeak-5.3 + # - squeak-5.2 + paths-ignore: + - '**.md' + schedule: + - cron: '0 0 * * *' # Build everyday at midnight + workflow_dispatch: + +jobs: + prepare-image: + strategy: + fail-fast: true + matrix: + smalltalk: + - Squeak-trunk + - Squeak64-trunk + # - Squeak-5.3 + # - Squeak64-5.3 + # - Squeak-5.2 + # - Squeak64-5.2 + # - Etoys-trunk + # - Etoys64-trunk + runs-on: windows-latest + name: ๐Ÿ›  Prepare image for ${{ matrix.smalltalk }} + env: + SMALLTALK_VERSION: ${{ matrix.smalltalk }} + steps: + - uses: actions/checkout@v2 + + - name: Prepare image + shell: bash + run: ./prepare_image.sh + timeout-minutes: 20 + + - name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: ${{ matrix.smalltalk }} + path: | + tmp/*.sources + tmp/*.image + tmp/*.changes + + - name: Export global environment + uses: actions/upload-artifact@v2 + with: + name: ${{ matrix.smalltalk }}-env + path: tmp/global-env + + + test-image: + needs: [prepare-image] + strategy: + fail-fast: true + matrix: + smalltalk: + - Squeak-trunk + - Squeak64-trunk + # - Squeak-5.3 + # - Squeak64-5.3 + # - Squeak-5.2 + # - Squeak64-5.2 + # - Etoys-trunk + # - Etoys64-trunk + runs-on: windows-latest + name: ๐Ÿงช Test image of ${{ matrix.smalltalk }} + env: + SMALLTALK_VERSION: ${{ matrix.smalltalk }} + steps: + - uses: actions/checkout@v2 + + - name: Import global environment + uses: actions/download-artifact@v2 + with: + name: ${{ matrix.smalltalk }}-env + path: tmp + + - name: Download artifacts + uses: actions/download-artifact@v2 + with: + name: ${{ matrix.smalltalk }} + path: tmp + + - name: "Set up SmalltalkCI" + # uses: hpi-swa/setup-smalltalkCI@v1 + uses: marceltaeumel/setup-smalltalkCI@marceltaeumel/install-path + with: + smalltalk-image: ${{ matrix.smalltalk }} + smalltalkCI-workspace: ${{ github.workspace }} + + - name: "Run tests" + continue-on-error: true + shell: bash + run: ./test_image.sh + timeout-minutes: 20 + + - name: Upload test results + uses: actions/upload-artifact@v2 + with: + name: ${{ matrix.smalltalk }}-tests + path: tmp/*.xml # smalltalkCI test results + + + prepare-bundles: + needs: [prepare-image] + strategy: + fail-fast: true + matrix: + smalltalk: + - Squeak-trunk + - Squeak64-trunk + # - Squeak-5.3 + # - Squeak64-5.3 + # - Squeak-5.2 + # - Squeak64-5.2 + # - Etoys-trunk + # - Etoys64-trunk + runs-on: macos-10.15 # fixed for xcnotary + name: ๐Ÿ“ฆ Prepare bundles for ${{ matrix.smalltalk }} + env: + SMALLTALK_VERSION: ${{ matrix.smalltalk }} + SHOULD_DEPLOY: ${{ endsWith(github.ref, 'squeak-trunk') }} + SHOULD_CODESIGN: ${{ endsWith(github.ref, 'squeak-trunk') }} + + steps: + - uses: actions/checkout@v2 + + - name: Import global environment + uses: actions/download-artifact@v2 + with: + name: ${{ matrix.smalltalk }}-env + path: tmp + + - name: Download artifacts + uses: actions/download-artifact@v2 + with: + name: ${{ matrix.smalltalk }} + path: tmp + + - run: ./prepare_bundles.sh + env: + CODESIGN_KEY: ${{ secrets.CODESIGN_KEY }} + CODESIGN_IV: ${{ secrets.CODESIGN_IV }} + CERT_IDENTITY: ${{ secrets.CERT_IDENTITY }} + CERT_PASSWORD: ${{ secrets.CERT_PASSWORD }} + NOTARIZATION_USER: ${{ secrets.NOTARIZATION_USER }} + NOTARIZATION_PASSWORD: ${{ secrets.NOTARIZATION_PASSWORD }} + + - name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: ${{ matrix.smalltalk }}-bundles + path: product/* + + - run: ./deploy_bundles.sh + if: env.SHOULD_DEPLOY == 'true' + env: + DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} + DEPLOY_IV: ${{ secrets.DEPLOY_IV }} + SSH_PUBLIC_KEY: ${{ secrets.SSH_PUBLIC_KEY }} + PROXY_PORT: ${{ secrets.PROXY_PORT }} + PROXY_HOST: ${{ secrets.PROXY_HOST }} + PROXY_USER: ${{ secrets.PROXY_USER }} + UPSTREAM_HOST: ${{ secrets.UPSTREAM_HOST }} + UPSTREAM_USER: ${{ secrets.UPSTREAM_USER }} diff --git a/.gitignore b/.gitignore index d2fd107..ba94793 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,11 @@ -*.sources -*.changes -*.image -*.p12 -*.cer -encrypted/ -.encrypted.zip +*.sources +*.changes +*.image +*.p12 +*.cer +secret*/ +.secret-*.zip +smalltalk-ci/repository/** +tmp/** +build/** +product/** diff --git a/.secret-codesign.zip.enc b/.secret-codesign.zip.enc new file mode 100644 index 0000000..e9d9aa7 Binary files /dev/null and b/.secret-codesign.zip.enc differ diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index c3757b7..0000000 --- a/.travis.yml +++ /dev/null @@ -1,44 +0,0 @@ -language: smalltalk - -os: osx - -# xcnotary requires Xcode 11 or later, but we can't build 32bit on macOS Catalina (10.15 or later) -osx_image: xcode11.3 - -smalltalk: - - Squeak-trunk - - Squeak64-trunk - # - Squeak-5.3 - # - Squeak64-5.3 - # - Squeak-5.2 - # - Squeak64-5.2 - # - Squeak-5.1 - # - Squeak64-5.1 - # - Squeak-5.0 - - # - Etoys64-trunk - # - Etoys-trunk - -# matrix: -# allow_failures: -# - smalltalk: Squeak64-trunk -# - smalltalk: Squeak64-5.1 -# - smalltalk: Squeak-5.0 # currently broken due to a stale test -# - smalltalk: Etoys64-trunk -# - smalltalk: Etoys-trunk - -# Increase display resolution (1176x885 max on Travis CI's macOS containers) -before_script: /Library/Application\ Support/VMware\ Tools/vmware-resolutionSet 1200 900 - -script: ./prepare.sh - -notifications: - email: - - squeak-dev@lists.squeakfoundation.org - slack: - rooms: - - squeak:ID1VVfPsB1X17YiDK9F1VUcS#trunk - template: - - "Build <%{build_url}|#%{build_number}> of %{result} in %{duration}" - on_success: change - on_failure: always diff --git a/README.md b/README.md index 58e745d..fecd557 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,22 @@ -# The Squeak/Smalltalk Programming System - -[![Build Status](https://travis-ci.com/squeak-smalltalk/squeak-app.svg?branch=squeak-trunk)](https://travis-ci.com/squeak-smalltalk/squeak-app) - -This is the code repository for Squeak's build system. - -A build works basically as follows. The [prepare.sh](prepare.sh) script downloads VMs from http://files.squeak.org/base/ and then invokes the following scripts: - -* [prepare_image.sh](prepare_image.sh) downloads a base image/changes/sources from http://files.squeak.org/base/ -* [prepare_image.st](prepare_image.st) updates the image and creates a `version.sh` file with the version information -* [prepare_aio.sh](prepare_aio.sh) builds the All-In-One -* [prepare_mac.sh](prepare_mac.sh) builds the Mac release -* [prepare_win.sh](prepare_win.sh) builds the Windows release -* [prepare_lin.sh](prepare_lin.sh) builds the Linux x86 release -* [prepare_armv6.sh](prepare_armv6.sh) builds the Linux ARM release - -Finally, [prepare.sh](prepare.sh) uploads everything to http://files.squeak.org/ -(e.g. bleeding-edge trunk builds go to http://files.squeak.org/trunk). +# The Squeak/Smalltalk Programming System + +[![Build Status](https://github.com/squeak-smalltalk/squeak-app/actions/workflows/bundle.yml/badge.svg)](https://github.com/squeak-smalltalk/squeak-app/actions/workflows/bundle.yml) + +This is the code repository for Squeak's build system. + +A build works basically as follows. First, 32-bit and 64-bit images are prepared and tested: + +* [prepare_image.sh](prepare_image.sh) downloads a base image/changes/sources from http://files.squeak.org/base/ +* [prepare_image.st](prepare_image.st) updates the image and creates a `version.sh` file with the version information +* [test_image.sh](test_image.sh) uses [smalltalkCI](https://github.com/hpi-swa/smalltalkCI) to run all tests and document the results + +Second, the [prepare-bundles.sh](prepare-bundles.sh) script downloads VMs from http://files.squeak.org/base/ and then creates the bundles through the following scripts: + +* [prepare_aio.sh](prepare_aio.sh) builds the All-In-One +* [prepare_mac.sh](prepare_mac.sh) builds the Mac release +* [prepare_win.sh](prepare_win.sh) builds the Windows release +* [prepare_lin.sh](prepare_lin.sh) builds the Linux x86 release +* [prepare_armv6.sh](prepare_armv6.sh) builds the Linux ARM release + +Finally, [deploy_bundles.sh](deploy_bundles.sh) uploads everything to http://files.squeak.org/ +(e.g., bleeding-edge trunk builds go to http://files.squeak.org/trunk). diff --git a/deploy_bundles.sh b/deploy_bundles.sh new file mode 100755 index 0000000..b86ff21 --- /dev/null +++ b/deploy_bundles.sh @@ -0,0 +1,97 @@ +#!/usr/bin/env bash +################################################################################ +# PROJECT: Squeak Bundle Generation +# FILE: deploy_bundles.sh +# CONTENT: Upload all bundles to files.squeak.org +# +# REQUIRES: +# SMALLTALK_VERSION ... e.g., Squeak64-trunk +# SHOULD_DEPLOY ... i.e., true or false +# product/*.zip +# product/*.dmg +# IMAGE_NAME +# IMAGE_BITS +#....BUNDLE_NAME_LIN +#....BUNDLE_NAME_MAC +#....BUNDLE_NAME_WIN +#....BUNDLE_NAME_ARM ... only on 32-bit +# DEPLOY_KEY ... i.e., for unlocking secret files +# DEPLOY_IV ... i.e., for unlocking secret files +# SSH_PUBLIC_KEY +# PROXY_PORT +# PROXY_HOST +# PROXY_USER +# UPSTREAM_HOST +# UPSTREAM_USER +# PROVIDES: +# - +# +# AUTHORS: Fabio Niephaus, Hasso Plattner Institute, Potsdam, Germany +# Marcel Taeumel, Hasso Plattner Institute, Potsdam, Germany +################################################################################ + +set -o errexit + +source "env_vars" +source "helpers.sh" + +[[ -z "${IMAGE_NAME}" ]] && exit 2 +[[ -z "${IMAGE_BITS}" ]] && exit 3 + +[[ -z "${BUNDLE_NAME_LIN}" ]] && exit 4 +[[ -z "${BUNDLE_NAME_MAC}" ]] && exit 5 +[[ -z "${BUNDLE_NAME_WIN}" ]] && exit 6 + +if is_32bit; then + [[ -z "${BUNDLE_NAME_ARM}" ]] && exit 7 +fi + +begin_group "...preparing deployment..." + +if [[ -z "${DEPLOY_KEY}" ]]; then + print_error "Cannot deploy because secret missing." + exit 1 +else + unlock_secret "deploy" "${DEPLOY_KEY}" "${DEPLOY_IV}" + readonly SSH_KEY_FILEPATH="${HOME_PATH}/secret-deploy/ssh_deploy_key" + readonly SSH_KEY_PATH="${HOME_PATH}/secret-deploy" + chmod 600 "${SSH_KEY_FILEPATH}" +fi + +end_group + +begin_group "...uploading all files to files.squeak.org.." + +readonly UPSTREAM_BASE="/var/www/files.squeak.org" + +if is_etoys; then + UPSTREAM_PATH="${UPSTREAM_BASE}/etoys/${SQUEAK_VERSION/Etoys/}" +else + UPSTREAM_PATH="${UPSTREAM_BASE}/${SQUEAK_VERSION/Squeak/}" +fi +UPSTREAM_PATH="${UPSTREAM_PATH}/${IMAGE_NAME}" + + +ssh-keyscan -t ecdsa-sha2-nistp256 -p "${PROXY_PORT}" "${PROXY_HOST}" 2>&1 | tee -a "${HOME}/.ssh/known_hosts" > /dev/null; +echo "${UPSTREAM_HOST} ecdsa-sha2-nistp256 ${SSH_PUBLIC_KEY}" | tee -a "${HOME}/.ssh/known_hosts" > /dev/null; +rsync -rvz --ignore-existing -e "ssh -o ProxyCommand='ssh -l ${PROXY_USER} -i ${SSH_KEY_FILEPATH} -p ${PROXY_PORT} -W %h:%p ${PROXY_HOST}' -l ${UPSTREAM_USER} -i ${SSH_KEY_FILEPATH}" "${PRODUCT_PATH}/" "${UPSTREAM_HOST}:${UPSTREAM_PATH}/"; + +end_group + +begin_group "...updating 'latest' symlinks on server..." + +LATEST_PREFIX="${UPSTREAM_BASE}/nightly/Squeak-latest-${IMAGE_BITS}bit" +SYMS_CMD="ln -f -s ${UPSTREAM_PATH}/${IMAGE_NAME}.zip ${LATEST_PREFIX}.zip" +SYMS_CMD="${SYMS_CMD} && ln -f -s ${UPSTREAM_PATH}/${BUNDLE_NAME_LIN}.zip ${LATEST_PREFIX}-Linux.zip" +SYMS_CMD="${SYMS_CMD} && ln -f -s ${UPSTREAM_PATH}/${BUNDLE_NAME_MAC}.dmg ${LATEST_PREFIX}-macOS.dmg" +SYMS_CMD="${SYMS_CMD} && ln -f -s ${UPSTREAM_PATH}/${BUNDLE_NAME_WIN}.zip ${LATEST_PREFIX}-Windows.zip" +if is_32bit; then + SYMS_CMD="${SYMS_CMD} && ln -f -s ${UPSTREAM_PATH}/${BUNDLE_NAME_ARM}.zip ${LATEST_PREFIX}-ARMv6.zip" +fi +ssh -o ProxyCommand="ssh -l ${PROXY_USER} -i ${SSH_KEY_FILEPATH} -p ${PROXY_PORT} -W %h:%p ${PROXY_HOST}" \ + -l "${UPSTREAM_USER}" -i "${SSH_KEY_FILEPATH}" "${UPSTREAM_HOST}" -t "${SYMS_CMD}" + +end_group + +# Remove sensitive information +rm -rf "${SSH_KEY_PATH}" diff --git a/env_vars b/env_vars new file mode 100644 index 0000000..bd54e3e --- /dev/null +++ b/env_vars @@ -0,0 +1,15 @@ +readonly HOME_PATH="$(pwd)" + +readonly FILES_BASE="http://files.squeak.org/base" +readonly RELEASE_URL="${FILES_BASE}/${SMALLTALK_VERSION/Etoys/Squeak}" + +readonly IMAGE_URL="${RELEASE_URL}/base.zip" +readonly VM_BASE="${RELEASE_URL}" + +readonly VM_LIN="vm-linux" +readonly VM_MAC="vm-macos" +readonly VM_WIN="vm-win" +readonly VM_ARM6="vm-armv6" + +readonly ICONS_PATH="${HOME_PATH}/icons" +readonly RELEASE_NOTES_PATH="${HOME_PATH}/release-notes" diff --git a/helpers.sh b/helpers.sh index f26333b..cad0956 100644 --- a/helpers.sh +++ b/helpers.sh @@ -1,5 +1,5 @@ is_64bit() { - [[ "${TRAVIS_SMALLTALK_VERSION}" == *"64-"* ]] + [[ "${SMALLTALK_VERSION}" == *"64-"* ]] } is_32bit() { @@ -7,15 +7,11 @@ is_32bit() { } is_etoys() { - [[ "${TRAVIS_SMALLTALK_VERSION}" == "Etoys"* ]] -} - -is_Squeak_50() { - [[ "${TRAVIS_SMALLTALK_VERSION}" == "Squeak-5.0" ]] + [[ "${SMALLTALK_VERSION}" == "Etoys"* ]] } is_trunk() { - [[ "${TRAVIS_SMALLTALK_VERSION}" == *"trunk"* ]] + [[ "${SMALLTALK_VERSION}" == *"trunk"* ]] } is_file() { @@ -26,28 +22,172 @@ is_dir() { [[ -d $1 ]] } -is_nonzero() { - [[ $1 -ne 0 ]] +should_deploy() { + [[ "${SHOULD_DEPLOY}" == "true" ]] } -is_deployment_branch() { - [[ "${TRAVIS_BRANCH}" == "${DEPLOYMENT_BRANCH}" ]] +should_codesign() { + [[ "${SHOULD_CODESIGN}" == "true" ]] } +readonly COLOR_RESET="\033[0m" +readonly COLOR_LIGHT_RED="\033[1;31m" +readonly COLOR_LIGHT_GREEN="\033[1;32m" +readonly COLOR_YELLOW="\033[1;33m" +readonly COLOR_LIGHT_BLUE="\033[1;34m" + print_info() { local message=$1 - echo -e "\033[34;1m${message}\033[0m" + echo -e "${COLOR_LIGHT_BLUE}${message}${COLOR_RESET}" +} + +print_warning() { + local message=$1 + echo -e "${COLOR_YELLOW}${message}${COLOR_RESET}" +} + +print_error() { + local message=$1 + echo -e "${COLOR_LIGHT_RED}${message}${COLOR_RESET}" +} + +print_done() { + echo -e "${COLOR_LIGHT_GREEN}...done.${COLOR_RESET}" +} + +begin_group() { + local title=$1 + echo -e "::group::${title}" +} + +end_group() { + print_done + echo "::endgroup::" +} + +download_and_extract_vm() { + local name=$1 + local url=$2 # e.g., files.squeak.org/base/Squeak-trunk/vm-win.zip + local target=$3 # e.g., tmp/vm-win + echo "...downloading and extracting ${name} VM..." + curl -f -s --retry 3 -o "${TMP_PATH}/vm.zip" "${url}" + unzip -q "${TMP_PATH}/vm.zip" -d "${target}" + rm "${TMP_PATH}/vm.zip" +} + +export_variable() { + local var_name=$1 + local var_value=$2 + if [[ ! -z ${GITHUB_ENV} ]]; then + echo "${var_name}=${var_value}" >> $GITHUB_ENV + echo "${var_name}=${var_value}" >> $GLOBAL_ENV + else + print_warning "...skipping export of $var_name outside GitHub Actions..." + fi +} + +import_variables() { + if is_file $GLOBAL_ENV; then + source $GLOBAL_ENV + else + echo "No global variables to import." + fi } -travis_fold() { - local action=$1 - local name=$2 - local title="${3:-}" +prepare_platform_vm() { + case $RUNNER_OS in + "Windows") + readonly VM_URL="${VM_BASE}/${VM_WIN}.zip" + readonly SMALLTALK_VM="${TMP_PATH}/vm/SqueakConsole.exe" + # Add other GNU tools (e.g., wget) for third-party build scripts + PATH=$PATH:/c/msys64/usr/bin + ;; + "Linux") + readonly VM_URL="${VM_BASE}/${VM_LIN}.zip" + readonly SMALLTALK_VM="${TMP_PATH}/vm/squeak" + ;; + "macOS") + readonly VM_URL="${VM_BASE}/${VM_MAC}.zip" + readonly SMALLTALK_VM="${TMP_PATH}/vm/Squeak.app/Contents/MacOS/Squeak" + ;; + esac + + download_and_extract_vm "$RUNNER_OS" "${VM_URL}" "${TMP_PATH}/vm" - if [[ "${TRAVIS:-}" = "true" ]]; then - echo -en "travis_fold:${action}:${name}\r\033[0K" + if [[ ! -f "${SMALLTALK_VM}" ]]; then + echo "Failed to locate VM executable." && exit 1 fi - if [[ -n "${title}" ]]; then - print_info "${title}" +} + +lock_secret() { + local name=secret-$1 + local key=$2 + local iv=$3 + + local secret_dir="${HOME_PATH}/${name}" + + if ! is_dir "${secret_dir}"; then + print_error "Failed to locate files to encrypt." + exit 1 fi + + zip -q -r "${HOME_PATH}/.${name}.zip" "${name}" + rm -r -d "${secret_dir}" + + openssl aes-256-cbc -e -in .${name}.zip -out .${name}.zip.enc \ + -pbkdf2 -K "${key}" -iv "${iv}" + rm .${name}.zip } + +unlock_secret() { + local name=secret-$1 + local key=$2 + local iv=$3 + + local secret_dir="${HOME_PATH}/${name}" + + if ! is_file .${name}.zip.enc; then + print_error "Failed to locate encrypted archive." + exit 1 + fi + + openssl aes-256-cbc -d -in .${name}.zip.enc -out .${name}.zip \ + -pbkdf2 -K "${key}" -iv "${iv}" + rm .${name}.zip.enc + + unzip -q .${name}.zip + rm .${name}.zip + + if ! is_dir "${secret_dir}"; then + print_error "Failed to locate decrypted files." + exit 1 + fi +} + +# Assure the existence of all working directories +readonly BUILD_PATH="${HOME_PATH}/build" +readonly PRODUCT_PATH="${HOME_PATH}/product" +readonly TMP_PATH="${HOME_PATH}/tmp" +mkdir -p "${BUILD_PATH}" "${PRODUCT_PATH}" "${TMP_PATH}" + +# Communicate variables beyond a single action +readonly GLOBAL_ENV="${TMP_PATH}/global-env" +import_variables + +# Assure $RUNNER_OS if not invoked from within GitHub Actions +if [[ -z "${RUNNER_OS}" ]]; then + case $(uname -s) in + Darwin*) + export RUNNER_OS="macOS" + ;; + Linux*) + export RUNNER_OS="Linux" + ;; + CYGWIN*|MINGW*) + export RUNNER_OS="Windows" + ;; + *) + echo "Unsupported platform." + exit 1 + esac +fi diff --git a/helpers_bundles.sh b/helpers_bundles.sh new file mode 100644 index 0000000..ced6442 --- /dev/null +++ b/helpers_bundles.sh @@ -0,0 +1,81 @@ +download_and_extract_all_vms() { + begin_group "Downloading and extracting all VMs..." + + echo "...downloading and sourcing VM versions file..." + curl -f -s --retry 3 -o "${TMP_PATH}/vm-versions" "${VM_BASE}/${VM_VERSIONS}" + source "${TMP_PATH}/vm-versions" + if [[ -z "${VERSION_VM_ARMV6}" ]] || [[ -z "${VERSION_VM_LINUX}" ]] || \ + [[ -z "${VERSION_VM_MACOS}" ]] || [[ -z "${VERSION_VM_WIN}" ]]; then + print_error "...could not determine all required VM versions!" + exit 1 + fi + + download_and_extract_vm "macOS" "${VM_BASE}/${VM_MAC}.zip" "${TMP_PATH}/${VM_MAC}" + download_and_extract_vm "Linux" "${VM_BASE}/${VM_LIN}.zip" "${TMP_PATH}/${VM_LIN}" + download_and_extract_vm "Windows" "${VM_BASE}/${VM_WIN}.zip" "${TMP_PATH}/${VM_WIN}" + + # ARMv6 currently only supported on 32-bit + if is_32bit; then + download_and_extract_vm "ARMv6" "${VM_BASE}/${VM_ARM6}.zip" "${TMP_PATH}/${VM_ARM6}" + fi + + end_group +} + +compress_into_product() { + target=$1 + echo "...compressing $target..." + pushd "${BUILD_PATH}" > /dev/null + # tar czf "${PRODUCT_PATH}/${target}.tar.gz" "./" + zip -q -r "${PRODUCT_PATH}/${target}.zip" "./" + popd > /dev/null +} + +compress_into_product_macOS() { + source_path=$1 + target_name=$2 + target_path="${PRODUCT_PATH}/${target_name}.dmg" + + if [[ ! $(type -t hdiutil) ]]; then + print_warning "...Cannot compress into DMG because hdiutil not found." + compress_into_product $target_name + return + fi + + echo "...compressing $target as DMG for macOS..." + TMP_DMG="temp.dmg" + hdiutil create -size 192m -volname "${target_name}" -srcfolder "${source_path}" \ + -fs HFS+ -fsargs "-c c=64,a=16,e=16" -format UDRW -nospotlight "${TMP_DMG}" + DEVICE="$(hdiutil attach -readwrite -noautoopen -nobrowse "${TMP_DMG}" | awk 'NR==1{print$1}')" + VOLUME="$(mount | grep "${DEVICE}" | sed 's/^[^ ]* on //;s/ ([^)]*)$//')" + hdiutil detach "${DEVICE}" + hdiutil convert "${TMP_DMG}" -format UDBZ -imagekey bzip2-level=6 -o "${target_path}" + rm -f "${TMP_DMG}" + +if should_codesign; then + do_codesign "${target_path}" # *.dmg + if ! is_trunk; then + do_notarize "${target_path}" # *.dmg + fi +fi +} + +reset_build_dir() { + rm -rf "${BUILD_PATH}" && mkdir "${BUILD_PATH}" +} + +copy_resources() { + local target=$1 + echo "...copying image files into bundle..." + cp "${TMP_PATH}/Squeak.image" "${target}/${IMAGE_NAME}.image" + cp "${TMP_PATH}/Squeak.changes" "${target}/${IMAGE_NAME}.changes" + cp "${TMP_PATH}/"*.sources "${target}/" + + cp -R "${RELEASE_NOTES_PATH}" "${target}/" + cp -R "${TMP_PATH}/locale" "${target}/" + + if is_etoys; then + cp "${TMP_PATH}/"*.pr "${target}/" + cp -R "${TMP_PATH}/ExampleEtoys" "${target}/" + fi +} diff --git a/helpers_codesign.sh b/helpers_codesign.sh new file mode 100644 index 0000000..e309c21 --- /dev/null +++ b/helpers_codesign.sh @@ -0,0 +1,126 @@ +prepare_codesign() { + + if [[ ! $(type -t prepare_codesign_$RUNNER_OS) ]]; then + print_warning "Cannot prepare code signing because platform not supported: ${RUNNER_OS}" + return + fi + + if [[ -z "${CODESIGN_KEY}" ]]; then + print_warning "Cannot prepare code signing because secret missing." + return + fi + + begin_group "...preparing code signing..." + unlock_secret "codesign" "${CODESIGN_KEY}" "${CODESIGN_IV}" + readonly CERT_FILEPATH_CER="{HOME_PATH}/secret-codesign/codesign.cer" + readonly CERT_FILEPATH_P12="{HOME_PATH}/secret-codesign/codesign.p12" + prepare_codesign_$RUNNER_OS + prepare_notarize_$RUNNER_OS + end_group +} + +cleanup_codesign() { + if [[ ! $(type -t prepare_codesign_$RUNNER_OS) ]]; then + print_warning "Cannot clean-up code signing because platform not supported: ${RUNNER_OS}" + return + fi + begin_group "...cleaning up code signing..." + cleanup_codesign_$RUNNER_OS + rm -r -d "{HOME_PATH}/secret-codesign" + end_group +} + +do_codesign() { + if [[ ! $(type -t codesign_$RUNNER_OS) ]]; then + print_warning "...not code signing because platform not supported: ${RUNNER_OS}." + return + fi + + if [[ -z "${CERT_IDENTITY}" ]]; then + print_warning "...not code signing because secret missing." + return + fi + + do_codesign_$RUNNER_OS $1 +} + +do_notarize() { + if [[ ! $(type -t notarize_$RUNNER_OS) ]]; then + print_warning "...not notarizing because platform not supported: ${RUNNER_OS}." + return + fi + + if [[ -z "${NOTARIZATION_USER}" ]]; then + print_warning "...not code signing because secret missing." + return + fi + + do_notarize_$RUNNER_OS $1 +} + +prepare_codesign_macOS() { + KEY_CHAIN=macos-build.keychain + KEY_CHAIN_PASSWORD=github-actions + + # Create the keychain with a password + security create-keychain -p "${KEY_CHAIN_PASSWORD}" "${KEY_CHAIN}" + # removing relock timeout on keychain + security set-keychain-settings "${KEY_CHAIN}" + # Add certificates to keychain and allow codesign to access them + security import "${CERT_FILEPATH_CER}" -k ~/Library/Keychains/"${KEY_CHAIN}" -T /usr/bin/codesign > /dev/null + security import "${CERT_FILEPATH_P12}" -k ~/Library/Keychains/"${KEY_CHAIN}" -P "${CERT_PASSWORD}" -T /usr/bin/codesign > /dev/null + # Make codesign work on macOS 10.12 or later (see https://git.io/JvE7X) + security set-key-partition-list -S apple-tool:,apple: -s -k "${KEY_CHAIN_PASSWORD}" "${KEY_CHAIN}" > /dev/null + + # Make the custom keychain default, so xcodebuild will use it for signing + security default-keychain -d user -s "${KEY_CHAIN}" + # Unlock the keychain + security unlock-keychain -p "${KEY_CHAIN_PASSWORD}" "${KEY_CHAIN}" +} + +prepare_notarize_macOS() { + # Store notarization password in keychain for xcnotary + xcrun altool --store-password-in-keychain-item "ALTOOL_PASSWORD" -u "${NOTARIZATION_USER}" -p "${NOTARIZATION_PASSWORD}" +} + + + +do_codesign_macOS() { + local target=$1 + + echo "...signing the bundle..." + + xattr -cr "${target}" # Remove all extended attributes from app bundle + + # Sign all plugin bundles + for d in "${target}/Contents/Resources/"*/; do + if [[ "${d}" == *".bundle/" ]]; then + codesign -s "${CERT_IDENTITY}" --force --deep --verbose "${d}" + fi + done + + # Sign the app bundle + codesign -s "${CERT_IDENTITY}" --force --deep --verbose --options=runtime \ + --entitlements "${MAC_TEMPLATE_PATH}/entitlements.plist" "${target}" +} + +do_notarize_macOS() { + local path=$1 + + if ! command -v xcnotary >/dev/null 2>&1; then + echo "...installing xcnotary helper..." + curl -sL https://github.com/akeru-inc/xcnotary/releases/download/v0.4.8/xcnotary-0.4.8.catalina.bottle.tar.gz | \ + tar -zxvf - --strip-components=3 xcnotary/0.4.8/bin/xcnotary + chmod +x xcnotary + fi + + echo "...notarizing the bundle..." + ./xcnotary notarize "${path}" \ + --developer-account "${NOTARIZATION_USER}" \ + --developer-password-keychain-item "ALTOOL_PASSWORD" +} + +cleanup_codesign_macOS() { + security delete-keychain "${KEY_CHAIN}" + #TODO: Remove ALTOOL_PASSWORD from local key chain +} diff --git a/localbuild.sh b/localbuild.sh index 4123de0..c233915 100755 --- a/localbuild.sh +++ b/localbuild.sh @@ -1,30 +1,30 @@ #!/bin/bash -git clean -fdx -export TRAVIS_BUILD_DIR="$(pwd)" -export TRAVIS_SMALLTALK_VERSION="Etoys-trunk" -# On non-Travis runs, just disable codesigning, security, and the extracting +export SMALLTALK_VERSION="${1:-Squeak64-trunk}" +export SHOULD_DEPLOY="${2:-false}" +export SHOULD_CODESIGN="${SHOULD_DEPLOY}" + +# On local runs, just disable code signing, security, and the extracting # of the signing key -mkdir encrypted -export UNZIPPATH=$(which unzip) + function codesign() { - echo "No codesigning in local build" + echo "No code signing in local build" } function security() { - echo "No security in local build" + echo "No security in local build" } function unzip() { - "$(which unzip)" $@ || true + "$(which unzip)" $@ || true } function curl() { - if [ "$1" == "-T" ]; then - echo "No uploading locally" - else - "$(which curl)" $@ - fi + if [ "$1" == "-T" ]; then + echo "No uploading locally" + else + "$(which curl)" $@ + fi } function brew() { - sudo $(which brew) $@ + echo "No auto-install in local build" } export -f codesign export -f security @@ -32,4 +32,14 @@ export -f unzip export -f curl export -f brew -exec ./prepare.sh +# git clean -fdx +# exec ./prepare_image.sh + +# export SMALLTALK_CI_HOME="../smalltalkCI" +# exec ./test_image.sh + +# source "tmp/version.sh" +# exec ./prepare_bundles.sh + +# export IMAGE_NAME="Squeak6.0alpha-20639-64bit" +# exec ./deploy_bundles.sh diff --git a/prepare.sh b/prepare.sh deleted file mode 100755 index 1469d0b..0000000 --- a/prepare.sh +++ /dev/null @@ -1,244 +0,0 @@ -#!/usr/bin/env bash -################################################################################ -# PROJECT: Squeak Bundle Generation -# FILE: prepare.sh -# CONTENT: Generate different bundles such as the All-in-One. -# -# AUTHORS: Fabio Niephaus, Hasso Plattner Institute, Potsdam, Germany -# Marcel Taeumel, Hasso Plattner Institute, Potsdam, Germany -################################################################################ - -set -o errexit - -if [[ -z "${TRAVIS_BUILD_DIR}" ]]; then - echo "Script needs to run on Travis CI" - exit 1 -fi - -readonly DEPLOYMENT_BRANCH="squeak-trunk" -readonly FILES_BASE="http://files.squeak.org/base" -readonly RELEASE_URL="${FILES_BASE}/${TRAVIS_SMALLTALK_VERSION/Etoys/Squeak}" -readonly IMAGE_URL="${RELEASE_URL}/base.zip" -readonly VM_BASE="${RELEASE_URL}" -readonly TARGET_URL="https://www.hpi.uni-potsdam.de/hirschfeld/artefacts/squeak/" -readonly TARGET_BASE="/var/www/files.squeak.org" - -readonly TEMPLATE_DIR="${TRAVIS_BUILD_DIR}/templates" -readonly AIO_TEMPLATE_DIR="${TEMPLATE_DIR}/all-in-one" -readonly LIN_TEMPLATE_DIR="${TEMPLATE_DIR}/linux" -readonly MAC_TEMPLATE_DIR="${TEMPLATE_DIR}/macos" -readonly WIN_TEMPLATE_DIR="${TEMPLATE_DIR}/win" - -readonly BUILD_DIR="${TRAVIS_BUILD_DIR}/build" -readonly PRODUCT_DIR="${TRAVIS_BUILD_DIR}/product" -readonly SCI_DIR="${TRAVIS_BUILD_DIR}/smalltalk-ci" -readonly TMP_DIR="${TRAVIS_BUILD_DIR}/tmp" -readonly ENCRYPTED_DIR="${TRAVIS_BUILD_DIR}/encrypted" - -readonly LOCALE_DIR="${TRAVIS_BUILD_DIR}/locale" -readonly ICONS_DIR="${TRAVIS_BUILD_DIR}/icons" -readonly RELEASE_NOTES_DIR="${TRAVIS_BUILD_DIR}/release-notes" - -readonly VM_BUILD="vm-build" -readonly VM_LIN="vm-linux" -readonly VM_MAC="vm-macos" -readonly VM_WIN="vm-win" -readonly VM_ARM6="vm-armv6" -readonly VM_VERSIONS="versions.txt" - -# version.sh file produced by image -readonly VERSION_FILE="${TMP_DIR}/version.sh" - -source "helpers.sh" - -if is_etoys; then - readonly SMALLTALK_NAME="Etoys" -else - readonly SMALLTALK_NAME="Squeak" -fi - -# Create build, product, and temp folders -mkdir -p "${BUILD_DIR}" "${PRODUCT_DIR}" "${TMP_DIR}" - -download_and_extract_vms() { - travis_fold start download_extract "...downloading and extracting all VMs..." - - echo "...downloading and sourcing VM versions file..." - curl -f -s --retry 3 -o "${TMP_DIR}/vm-versions" "${VM_BASE}/${VM_VERSIONS}" - source "${TMP_DIR}/vm-versions" - if [[ -z "${VERSION_VM_ARMV6}" ]] || [[ -z "${VERSION_VM_LINUX}" ]] || \ - [[ -z "${VERSION_VM_MACOS}" ]] || [[ -z "${VERSION_VM_WIN}" ]]; then - echo "Could not determine all required VM versions." - exit 1 - fi - - echo "...downloading and extracting macOS VM..." - curl -f -s --retry 3 -o "${TMP_DIR}/${VM_MAC}.zip" "${VM_BASE}/${VM_MAC}.zip" - unzip -q "${TMP_DIR}/${VM_MAC}.zip" -d "${TMP_DIR}/${VM_MAC}" - if is_dir "${TMP_DIR}/${VM_MAC}/Squeak.app"; then - readonly SMALLTALK_VM="${TMP_DIR}/${VM_MAC}/Squeak.app/Contents/MacOS/Squeak" - elif is_dir "${TMP_DIR}/${VM_MAC}/CogSpur.app"; then - readonly SMALLTALK_VM="${TMP_DIR}/${VM_MAC}/CogSpur.app/Contents/MacOS/Squeak" - else - echo "Failed to locate macOS VM app." && exit 1 - fi - - echo "...downloading and extracting Linux VM..." - curl -f -s --retry 3 -o "${TMP_DIR}/${VM_LIN}.zip" "${VM_BASE}/${VM_LIN}.zip" - unzip -q "${TMP_DIR}/${VM_LIN}.zip" -d "${TMP_DIR}/${VM_LIN}" - - echo "...downloading and extracting Windows VM..." - curl -f -s --retry 3 -o "${TMP_DIR}/${VM_WIN}.zip" "${VM_BASE}/${VM_WIN}.zip" - unzip -q "${TMP_DIR}/${VM_WIN}.zip" -d "${TMP_DIR}/${VM_WIN}" - - # ARMv6 currently only supported on 32-bit - if is_32bit; then - echo "...downloading and extracting ARMv6 VM..." - curl -f -s --retry 3 -o "${TMP_DIR}/${VM_ARM6}.zip" "${VM_BASE}/${VM_ARM6}.zip" - unzip -q "${TMP_DIR}/${VM_ARM6}.zip" -d "${TMP_DIR}/${VM_ARM6}" - fi - travis_fold end download_extract -} - -compress() { - target=$1 - echo "...compressing the bundle..." - pushd "${BUILD_DIR}" > /dev/null - # tar czf "${PRODUCT_DIR}/${target}.tar.gz" "./" - zip -q -r "${PRODUCT_DIR}/${target}.zip" "./" - popd > /dev/null -} - -reset_buildir() { - rm -rf "${BUILD_DIR}" && mkdir "${BUILD_DIR}" -} - -copy_resources() { - local target=$1 - echo "...copying image files into bundle..." - cp "${TMP_DIR}/Squeak.image" "${target}/${IMAGE_NAME}.image" - cp "${TMP_DIR}/Squeak.changes" "${target}/${IMAGE_NAME}.changes" - cp "${TMP_DIR}/"*.sources "${target}/" - if ! is_Squeak_50; then - cp -R "${RELEASE_NOTES_DIR}" "${target}/" - cp -R "${TMP_DIR}/locale" "${target}/" - fi - if is_etoys; then - cp "${TMP_DIR}/"*.pr "${target}/" - cp -R "${TMP_DIR}/ExampleEtoys" "${target}/" - fi -} - -codesign_bundle() { - local target=$1 - - echo "...signing the bundle..." - - xattr -cr "${target}" # Remove all extended attributes from app bundle - - # Sign all plugin bundles - for d in "${target}/Contents/Resources/"*/; do - if [[ "${d}" == *".bundle/" ]]; then - codesign -s "${SIGN_IDENTITY}" --force --deep --verbose "${d}" - fi - done - - # Sign the app bundle - codesign -s "${SIGN_IDENTITY}" --force --deep --verbose --options=runtime \ - --entitlements "${MAC_TEMPLATE_DIR}/entitlements.plist" "${target}" -} - -notarize() { - local path=$1 - - if ! command -v xcnotary >/dev/null 2>&1; then - echo "...installing xcnotary helper..." - curl -sL https://github.com/akeru-inc/xcnotary/releases/download/v0.4.0/xcnotary-0.4.0.catalina.bottle.tar.gz | \ - tar -zxvf - --strip-components=3 xcnotary/0.4.0/bin/xcnotary - chmod +x xcnotary - fi - - echo "...notarizing the bundle..." - ./xcnotary notarize "${path}" \ - --developer-account "${NOTARIZATION_USER}" \ - --developer-password-keychain-item "ALTOOL_PASSWORD" -} - -download_and_extract_vms - -source "prepare_image.sh" - -if is_deployment_branch; then - # Decrypt and extract sensitive files - openssl aes-256-cbc -K $encrypted_7fdec7aaa5ee_key \ - -iv $encrypted_7fdec7aaa5ee_iv -in .encrypted.zip.enc -out .encrypted.zip -d - unzip -q .encrypted.zip - if ! is_dir "${ENCRYPTED_DIR}"; then - echo "Failed to locate decrypted files." - exit 1 - fi - - travis_fold start macos_signing "...preparing signing..." - KEY_CHAIN=macos-build.keychain - # Create the keychain with a password - security create-keychain -p travis "${KEY_CHAIN}" - # Make the custom keychain default, so xcodebuild will use it for signing - security default-keychain -s "${KEY_CHAIN}" - # Unlock the keychain - security unlock-keychain -p travis "${KEY_CHAIN}" - # Add certificates to keychain and allow codesign to access them - security import "${ENCRYPTED_DIR}/sign.cer" -k ~/Library/Keychains/"${KEY_CHAIN}" -T /usr/bin/codesign > /dev/null - security import "${ENCRYPTED_DIR}/sign.p12" -k ~/Library/Keychains/"${KEY_CHAIN}" -P "${CERT_PASSWORD}" -T /usr/bin/codesign > /dev/null - # Make codesign work on macOS 10.12 or later (see https://git.io/JvE7X) - security set-key-partition-list -S apple-tool:,apple: -s -k travis "${KEY_CHAIN}" > /dev/null - # Store notarization password in keychain for xcnotary - xcrun altool --store-password-in-keychain-item "ALTOOL_PASSWORD" -u "${NOTARIZATION_USER}" -p "${NOTARIZATION_PASSWORD}" - travis_fold end macos_signing -fi - -reset_buildir -source "prepare_aio.sh" -reset_buildir -source "prepare_mac.sh" -reset_buildir -source "prepare_lin.sh" -reset_buildir -source "prepare_win.sh" -reset_buildir -if is_32bit; then - source "prepare_armv6.sh" -fi - -if is_deployment_branch; then - travis_fold start upload_files "...uploading all files to files.squeak.org..." - if is_etoys; then - TARGET_PATH="${TARGET_BASE}/etoys/${SQUEAK_VERSION/Etoys/}" - else - TARGET_PATH="${TARGET_BASE}/${SQUEAK_VERSION/Squeak/}" - fi - TARGET_PATH="${TARGET_PATH}/${IMAGE_NAME}" - chmod 600 "${ENCRYPTED_DIR}/ssh_deploy_key" - ssh-keyscan -t ecdsa-sha2-nistp256 -p "${ENCRYPTED_PROXY_PORT}" "${ENCRYPTED_PROXY_HOST}" 2>&1 | tee -a "${HOME}/.ssh/known_hosts" > /dev/null; - echo "${ENCRYPTED_HOST} ecdsa-sha2-nistp256 ${ENCRYPTED_PUBLIC_KEY}" | tee -a "${HOME}/.ssh/known_hosts" > /dev/null; - rsync -rvz --ignore-existing -e "ssh -o ProxyCommand='ssh -l ${ENCRYPTED_PROXY_USER} -i ${ENCRYPTED_DIR}/ssh_deploy_key -p ${ENCRYPTED_PROXY_PORT} -W %h:%p ${ENCRYPTED_PROXY_HOST}' -l ${ENCRYPTED_USER} -i ${ENCRYPTED_DIR}/ssh_deploy_key" "${PRODUCT_DIR}/" "${ENCRYPTED_HOST}:${TARGET_PATH}/"; - travis_fold end upload_files - - travis_fold start update_symlinks "...updating latest symlinks on server..." - LATEST_PREFIX="${TARGET_BASE}/nightly/Squeak-latest-${IMAGE_BITS}bit" - SYMS_CMD="ln -f -s ${TARGET_PATH}/${IMAGE_NAME}.zip ${LATEST_PREFIX}.zip" - SYMS_CMD="${SYMS_CMD} && ln -f -s ${TARGET_PATH}/${BUNDLE_NAME_LIN}.zip ${LATEST_PREFIX}-Linux.zip" - SYMS_CMD="${SYMS_CMD} && ln -f -s ${TARGET_PATH}/${BUNDLE_NAME_MAC}.dmg ${LATEST_PREFIX}-macOS.dmg" - SYMS_CMD="${SYMS_CMD} && ln -f -s ${TARGET_PATH}/${BUNDLE_NAME_WIN}.zip ${LATEST_PREFIX}-Windows.zip" - if is_32bit; then - SYMS_CMD="${SYMS_CMD} && ln -f -s ${TARGET_PATH}/${BUNDLE_NAME_ARM}.zip ${LATEST_PREFIX}-ARMv6.zip" - fi - ssh -o ProxyCommand="ssh -l ${ENCRYPTED_PROXY_USER} -i ${ENCRYPTED_DIR}/ssh_deploy_key -p ${ENCRYPTED_PROXY_PORT} -W %h:%p ${ENCRYPTED_PROXY_HOST}" \ - -l "${ENCRYPTED_USER}" -i "${ENCRYPTED_DIR}/ssh_deploy_key" "${ENCRYPTED_HOST}" -t "${SYMS_CMD}" - travis_fold end update_symlinks - - # Remove sensitive information - rm -rf "${ENCRYPTED_DIR}" - security delete-keychain "${KEY_CHAIN}" -else - echo "...not uploading files because this is not the '${DEPLOYMENT_BRANCH}'' branch." -fi diff --git a/prepare_aio.sh b/prepare_aio.sh deleted file mode 100755 index c3058d1..0000000 --- a/prepare_aio.sh +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/env bash -################################################################################ -# PROJECT: Squeak Bundle Generation -# FILE: prepare_aio.sh -# CONTENT: Generate the All-in-One bundle. -# -# AUTHORS: Fabio Niephaus, Hasso Plattner Institute, Potsdam, Germany -# Marcel Taeumel, Hasso Plattner Institute, Potsdam, Germany -################################################################################ - -travis_fold start aio_bundle "Creating All-in-one bundle for ${TRAVIS_SMALLTALK_VERSION}..." -BUNDLE_NAME_AIO="${IMAGE_NAME}-All-in-One" -BUNDLE_ID_AIO="org.squeak.$(echo ${SQUEAK_VERSION} | tr '[:upper:]' '[:lower:]')-aio-${IMAGE_BITS}bit" -APP_NAME="${BUNDLE_NAME_AIO}.app" -APP_DIR="${BUILD_DIR}/${APP_NAME}" -CONTENTS_DIR="${APP_DIR}/Contents" -RESOURCES_DIR="${CONTENTS_DIR}/Resources" - -VM_ARM_TARGET="${CONTENTS_DIR}/Linux-ARM" -if [[ "${IMAGE_BITS}" == "64" ]]; then - VM_LIN_TARGET="${CONTENTS_DIR}/Linux-x86_64" -else - VM_LIN_TARGET="${CONTENTS_DIR}/Linux-i686" -fi -VM_MAC_TARGET="${CONTENTS_DIR}/MacOS" -VM_WIN_TARGET="${CONTENTS_DIR}/Win32" - -echo "...copying VMs into bundle..." -cp -R "${TMP_DIR}/${VM_MAC}/Squeak.app" "${APP_DIR}" -if is_32bit; then - cp -R "${TMP_DIR}/${VM_ARM6}" "${VM_ARM_TARGET}" -fi -cp -R "${TMP_DIR}/${VM_LIN}" "${VM_LIN_TARGET}" -cp -R "${TMP_DIR}/${VM_WIN}" "${VM_WIN_TARGET}" - -copy_resources "${RESOURCES_DIR}" - -echo "...merging template..." -cp "${AIO_TEMPLATE_DIR}/squeak.bat" "${BUILD_DIR}/" -cp "${AIO_TEMPLATE_DIR}/squeak.sh" "${BUILD_DIR}/" -cp "${AIO_TEMPLATE_DIR}/Squeak.app/Contents/Info.plist" "${CONTENTS_DIR}/" -cp "${ICONS_DIR}/${SMALLTALK_NAME}"*.icns "${RESOURCES_DIR}/" -ENGLISH_DIR="${AIO_TEMPLATE_DIR}/Squeak.app/Contents/Resources/English.lproj" -if ! is_Squeak_50; then - cp "${ENGLISH_DIR}/Credits.rtf" "${RESOURCES_DIR}/English.lproj/" -fi -cp "${AIO_TEMPLATE_DIR}/Squeak.app/Contents/Win32/Squeak.ini" "${VM_WIN_TARGET}/" - -echo "...setting permissions..." -chmod +x "${VM_LIN_TARGET}/squeak" "${VM_MAC_TARGET}/Squeak" "${VM_WIN_TARGET}/Squeak.exe" \ - "${BUILD_DIR}/squeak.sh" "${BUILD_DIR}/squeak.bat" - -echo "...applying various templates (squeak.sh, Info.plist, etc)..." -# squeak.bat launcher -sed -i ".bak" "s/%APP_NAME%/${APP_NAME}/g" "${BUILD_DIR}/squeak.bat" -sed -i ".bak" "s/%SqueakImageName%/${IMAGE_NAME}.image/g" "${BUILD_DIR}/squeak.bat" -rm -f "${BUILD_DIR}/squeak.bat.bak" -# squeak.sh launcher -sed -i ".bak" "s/%APP_NAME%/${APP_NAME}/g" "${BUILD_DIR}/squeak.sh" -sed -i ".bak" "s/%SqueakImageName%/${IMAGE_NAME}.image/g" "${BUILD_DIR}/squeak.sh" -sed -i ".bak" "s/%IMAGE_BITS%/${IMAGE_BITS}/g" "${BUILD_DIR}/squeak.sh" -rm -f "${BUILD_DIR}/squeak.sh.bak" -# Info.plist -sed -i ".bak" "s/%SmalltalkName%/${SMALLTALK_NAME}/g" "${CONTENTS_DIR}/Info.plist" -sed -i ".bak" "s/%CFBundleGetInfoString%/${BUNDLE_NAME_AIO}/g" "${CONTENTS_DIR}/Info.plist" -sed -i ".bak" "s/%CFBundleIdentifier%/${BUNDLE_ID_AIO}/g" "${CONTENTS_DIR}/Info.plist" -sed -i ".bak" "s/%CFBundleName%/${SMALLTALK_NAME}/g" "${CONTENTS_DIR}/Info.plist" -sed -i ".bak" "s/%CFBundleShortVersionString%/${SQUEAK_VERSION_NUMBER}/g" "${CONTENTS_DIR}/Info.plist" -sed -i ".bak" "s/%CFBundleVersion%/${IMAGE_BITS} bit/g" "${CONTENTS_DIR}/Info.plist" -sed -i ".bak" "s/%SqueakImageName%/${IMAGE_NAME}.image/g" "${CONTENTS_DIR}/Info.plist" -rm -f "${CONTENTS_DIR}/Info.plist.bak" -# Squeak.ini (consistent with contents in Info.plist) -sed -i ".bak" "s/%WindowTitle%/${WINDOW_TITLE}/g" "${VM_WIN_TARGET}/Squeak.ini" -rm -f "${VM_WIN_TARGET}/Squeak.ini.bak" -# Remove .map files from $VM_WIN_TARGET -rm -f "${VM_WIN_TARGET}/"*.map - -# Signing the macOS application -codesign_bundle "${APP_DIR}" - -if is_deployment_branch && ! is_trunk; then - notarize "${APP_DIR}" -fi - -compress "${BUNDLE_NAME_AIO}" - -echo "...done." - -travis_fold end aio_bundle diff --git a/prepare_bundle_aio.sh b/prepare_bundle_aio.sh new file mode 100755 index 0000000..c4d33bc --- /dev/null +++ b/prepare_bundle_aio.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash +################################################################################ +# PROJECT: Squeak Bundle Generation +# FILE: prepare_bundle_aio.sh +# CONTENT: Generate the All-in-One bundle. +# +# AUTHORS: Fabio Niephaus, Hasso Plattner Institute, Potsdam, Germany +# Marcel Taeumel, Hasso Plattner Institute, Potsdam, Germany +################################################################################ + +begin_group "Creating All-in-one bundle for ${SMALLTALK_VERSION}..." +BUNDLE_NAME_AIO="${IMAGE_NAME}-All-in-One" +export_variable "BUNDLE_NAME_AIO" "${BUNDLE_NAME_AIO}" +BUNDLE_ID_AIO="org.squeak.$(echo ${SQUEAK_VERSION} | tr '[:upper:]' '[:lower:]')-aio-${IMAGE_BITS}bit" +APP_NAME="${BUNDLE_NAME_AIO}.app" +APP_PATH="${BUILD_PATH}/${APP_NAME}" +CONTENTS_PATH="${APP_PATH}/Contents" +RESOURCES_PATH="${CONTENTS_PATH}/Resources" + +VM_ARM_TARGET="${CONTENTS_PATH}/Linux-ARM" +if [[ "${IMAGE_BITS}" == "64" ]]; then + VM_LIN_TARGET="${CONTENTS_PATH}/Linux-x86_64" +else + VM_LIN_TARGET="${CONTENTS_PATH}/Linux-i686" +fi +VM_MAC_TARGET="${CONTENTS_PATH}/MacOS" +VM_WIN_TARGET="${CONTENTS_PATH}/Win32" + +echo "...copying VMs into bundle..." +cp -R "${TMP_PATH}/${VM_MAC}/Squeak.app" "${APP_PATH}" +if is_32bit; then + cp -R "${TMP_PATH}/${VM_ARM6}" "${VM_ARM_TARGET}" +fi +cp -R "${TMP_PATH}/${VM_LIN}" "${VM_LIN_TARGET}" +cp -R "${TMP_PATH}/${VM_WIN}" "${VM_WIN_TARGET}" + +copy_resources "${RESOURCES_PATH}" + +echo "...merging template..." +cp "${AIO_TEMPLATE_PATH}/squeak.bat" "${BUILD_PATH}/" +cp "${AIO_TEMPLATE_PATH}/squeak.sh" "${BUILD_PATH}/" +cp "${AIO_TEMPLATE_PATH}/Squeak.app/Contents/Info.plist" "${CONTENTS_PATH}/" +cp "${ICONS_PATH}/${SMALLTALK_NAME}"*.icns "${RESOURCES_PATH}/" +ENGLISH_PATH="${AIO_TEMPLATE_PATH}/Squeak.app/Contents/Resources/English.lproj" +cp "${ENGLISH_PATH}/Credits.rtf" "${RESOURCES_PATH}/English.lproj/" +cp "${AIO_TEMPLATE_PATH}/Squeak.app/Contents/Win32/Squeak.ini" "${VM_WIN_TARGET}/" + +echo "...setting permissions..." +chmod +x "${VM_LIN_TARGET}/squeak" "${VM_MAC_TARGET}/Squeak" "${VM_WIN_TARGET}/Squeak.exe" \ + "${BUILD_PATH}/squeak.sh" "${BUILD_PATH}/squeak.bat" + +echo "...applying various templates (squeak.sh, Info.plist, etc)..." +# squeak.bat launcher +sed -i".bak" "s/%APP_NAME%/${APP_NAME}/g" "${BUILD_PATH}/squeak.bat" +sed -i".bak" "s/%SqueakImageName%/${IMAGE_NAME}.image/g" "${BUILD_PATH}/squeak.bat" +rm -f "${BUILD_PATH}/squeak.bat.bak" +# squeak.sh launcher +sed -i".bak" "s/%APP_NAME%/${APP_NAME}/g" "${BUILD_PATH}/squeak.sh" +sed -i".bak" "s/%SqueakImageName%/${IMAGE_NAME}.image/g" "${BUILD_PATH}/squeak.sh" +sed -i".bak" "s/%IMAGE_BITS%/${IMAGE_BITS}/g" "${BUILD_PATH}/squeak.sh" +rm -f "${BUILD_PATH}/squeak.sh.bak" +# Info.plist +sed -i".bak" "s/%SmalltalkName%/${SMALLTALK_NAME}/g" "${CONTENTS_PATH}/Info.plist" +sed -i".bak" "s/%CFBundleGetInfoString%/${BUNDLE_NAME_AIO}/g" "${CONTENTS_PATH}/Info.plist" +sed -i".bak" "s/%CFBundleIdentifier%/${BUNDLE_ID_AIO}/g" "${CONTENTS_PATH}/Info.plist" +sed -i".bak" "s/%CFBundleName%/${SMALLTALK_NAME}/g" "${CONTENTS_PATH}/Info.plist" +sed -i".bak" "s/%CFBundleShortVersionString%/${SQUEAK_VERSION_NUMBER}/g" "${CONTENTS_PATH}/Info.plist" +sed -i".bak" "s/%CFBundleVersion%/${IMAGE_BITS} bit/g" "${CONTENTS_PATH}/Info.plist" +sed -i".bak" "s/%SqueakImageName%/${IMAGE_NAME}.image/g" "${CONTENTS_PATH}/Info.plist" +rm -f "${CONTENTS_PATH}/Info.plist.bak" +# Squeak.ini (consistent with contents in Info.plist) +sed -i".bak" "s/%WindowTitle%/${WINDOW_TITLE}/g" "${VM_WIN_TARGET}/Squeak.ini" +rm -f "${VM_WIN_TARGET}/Squeak.ini.bak" +# Remove .map files from $VM_WIN_TARGET +rm -f "${VM_WIN_TARGET}/"*.map + +if should_codesign; then + do_codesign "${APP_PATH}" # *.app + if ! is_trunk; then + do_notarize "${APP_PATH}" # *.app + fi +fi + +compress_into_product "${BUNDLE_NAME_AIO}" +reset_build_dir + +end_group diff --git a/prepare_lin.sh b/prepare_bundle_linux.sh similarity index 50% rename from prepare_lin.sh rename to prepare_bundle_linux.sh index 77a43a1..65bb939 100755 --- a/prepare_lin.sh +++ b/prepare_bundle_linux.sh @@ -1,33 +1,35 @@ #!/usr/bin/env bash ################################################################################ # PROJECT: Squeak Bundle Generation -# FILE: prepare_lin.sh +# FILE: prepare_bundle_linux.sh # CONTENT: Generate bundle for Linux. # # AUTHORS: Fabio Niephaus, Hasso Plattner Institute, Potsdam, Germany # Marcel Taeumel, Hasso Plattner Institute, Potsdam, Germany ################################################################################ -travis_fold start linux_bundle "Creating Linux bundle for ${TRAVIS_SMALLTALK_VERSION}..." +begin_group "Creating Linux bundle for ${SMALLTALK_VERSION}..." BUNDLE_NAME_LIN="${IMAGE_NAME}-${VERSION_VM_LINUX}-Linux" -BUNDLE_DIR="${BUILD_DIR}/${BUNDLE_NAME_LIN}" -VM_DIR="${BUNDLE_DIR}/bin" -SHARED_DIR="${BUNDLE_DIR}/shared" +export_variable "BUNDLE_NAME_LIN" "${BUNDLE_NAME_LIN}" +BUNDLE_PATH="${BUILD_PATH}/${BUNDLE_NAME_LIN}" +VM_PATH="${BUNDLE_PATH}/bin" +SHARED_PATH="${BUNDLE_PATH}/shared" echo "...creating directories..." -mkdir -p "${BUNDLE_DIR}" "${VM_DIR}" "${SHARED_DIR}" +mkdir -p "${BUNDLE_PATH}" "${VM_PATH}" "${SHARED_PATH}" echo "...copying Linux VM..." -cp -R "${TMP_DIR}/${VM_LIN}/lib/squeak/"*/ "${VM_DIR}" +cp -R "${TMP_PATH}/${VM_LIN}/lib/squeak/"*/* "${VM_PATH}" -copy_resources "${SHARED_DIR}" +copy_resources "${SHARED_PATH}" echo "...merging template..." -cp "${LIN_TEMPLATE_DIR}/squeak.sh" "${BUNDLE_DIR}/" +cp "${LIN_TEMPLATE_PATH}/squeak.sh" "${BUNDLE_PATH}/" echo "...setting permissions..." -chmod +x "${VM_DIR}/squeak" "${BUNDLE_DIR}/squeak.sh" +chmod +x "${VM_PATH}/squeak" "${BUNDLE_PATH}/squeak.sh" -compress "${BUNDLE_NAME_LIN}" +compress_into_product "${BUNDLE_NAME_LIN}" +reset_build_dir -travis_fold end linux_bundle +end_group diff --git a/prepare_armv6.sh b/prepare_bundle_linux_armv6.sh similarity index 51% rename from prepare_armv6.sh rename to prepare_bundle_linux_armv6.sh index 70c571a..2f7ca0c 100755 --- a/prepare_armv6.sh +++ b/prepare_bundle_linux_armv6.sh @@ -1,33 +1,35 @@ #!/usr/bin/env bash ################################################################################ # PROJECT: Squeak Bundle Generation -# FILE: prepare_lin.sh +# FILE: prepare_bundle_linux_armv6.sh # CONTENT: Generate bundle for ARMv6. # # AUTHORS: Fabio Niephaus, Hasso Plattner Institute, Potsdam, Germany # Marcel Taeumel, Hasso Plattner Institute, Potsdam, Germany ################################################################################ -travis_fold start armv6_bundle "Creating ARMv6 bundle for ${TRAVIS_SMALLTALK_VERSION}..." +begin_group "Creating ARMv6 bundle for ${SMALLTALK_VERSION}..." BUNDLE_NAME_ARM="${IMAGE_NAME}-${VERSION_VM_ARMV6}-ARMv6" -BUNDLE_DIR="${BUILD_DIR}/${BUNDLE_NAME_ARM}" -VM_DIR="${BUNDLE_DIR}/bin" -SHARED_DIR="${BUNDLE_DIR}/shared" +export_variable "BUNDLE_NAME_ARM" "${BUNDLE_NAME_ARM}" +BUNDLE_PATH="${BUILD_PATH}/${BUNDLE_NAME_ARM}" +VM_PATH="${BUNDLE_PATH}/bin" +SHARED_PATH="${BUNDLE_PATH}/shared" echo "...creating directories..." -mkdir -p "${BUNDLE_DIR}" "${VM_DIR}" "${SHARED_DIR}" +mkdir -p "${BUNDLE_PATH}" "${VM_PATH}" "${SHARED_PATH}" echo "...copying ARMv6 VM..." -cp -R "${TMP_DIR}/${VM_ARM6}/lib/squeak/"*/ "${VM_DIR}" +cp -R "${TMP_PATH}/${VM_ARM6}/lib/squeak/"*/ "${VM_PATH}" -copy_resources "${SHARED_DIR}" +copy_resources "${SHARED_PATH}" echo "...merging template..." -cp "${LIN_TEMPLATE_DIR}/squeak.sh" "${BUNDLE_DIR}/" +cp "${LIN_TEMPLATE_PATH}/squeak.sh" "${BUNDLE_PATH}/" echo "...setting permissions..." -chmod +x "${VM_DIR}/squeak" +chmod +x "${VM_PATH}/squeak" -compress "${BUNDLE_NAME_ARM}" +compress_into_product "${BUNDLE_NAME_ARM}" +reset_build_dir -travis_fold end armv6_bundle +end_group diff --git a/prepare_bundle_macos.sh b/prepare_bundle_macos.sh new file mode 100755 index 0000000..d623ebe --- /dev/null +++ b/prepare_bundle_macos.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash +################################################################################ +# PROJECT: Squeak Bundle Generation +# FILE: prepare_bundle_macos.sh +# CONTENT: Generate bundle for macOS. +# +# AUTHORS: Fabio Niephaus, Hasso Plattner Institute, Potsdam, Germany +# Marcel Taeumel, Hasso Plattner Institute, Potsdam, Germany +################################################################################ + +begin_group "Creating macOS bundle for ${SMALLTALK_VERSION}..." +BUNDLE_NAME_MAC="${IMAGE_NAME}-${VERSION_VM_MACOS}-macOS" +export_variable "BUNDLE_NAME_MAC" "${BUNDLE_NAME_MAC}" +BUNDLE_ID_MAC="org.squeak.$(echo ${SQUEAK_VERSION} | tr '[:upper:]' '[:lower:]')-${IMAGE_BITS}bit" +APP_NAME="${IMAGE_NAME}.app" +APP_PATH="${BUILD_PATH}/${APP_NAME}" +CONTENTS_PATH="${APP_PATH}/Contents" +RESOURCES_PATH="${CONTENTS_PATH}/Resources" +VM_MAC_TARGET="${CONTENTS_PATH}/MacOS" + +echo "...copying macOS VM ..." +if is_dir "${TMP_PATH}/${VM_MAC}/Squeak.app"; then + cp -R "${TMP_PATH}/${VM_MAC}/Squeak.app" "${APP_PATH}" +else + echo "Unable to locate macOS VM." && exit 1 +fi + +copy_resources "${RESOURCES_PATH}" + +echo "...merging template..." +cp "${AIO_TEMPLATE_PATH}/Squeak.app/Contents/Info.plist" "${CONTENTS_PATH}/" +cp "${ICONS_PATH}/${SMALLTALK_NAME}"*.icns "${RESOURCES_PATH}/" +ENGLISH_PATH="${AIO_TEMPLATE_PATH}/Squeak.app/Contents/Resources/English.lproj" +cp "${ENGLISH_PATH}/Credits.rtf" "${RESOURCES_PATH}/English.lproj/" + +echo "...setting permissions..." +chmod +x "${VM_MAC_TARGET}/Squeak" + +echo "...patching Info.plist..." +# Info.plist +sed -i".bak" "s/%SmalltalkName%/${SMALLTALK_NAME}/g" "${CONTENTS_PATH}/Info.plist" +sed -i".bak" "s/%CFBundleGetInfoString%/${BUNDLE_NAME_MAC}/g" "${CONTENTS_PATH}/Info.plist" +sed -i".bak" "s/%CFBundleIdentifier%/${BUNDLE_ID_MAC}/g" "${CONTENTS_PATH}/Info.plist" +sed -i".bak" "s/%CFBundleName%/${SMALLTALK_NAME}/g" "${CONTENTS_PATH}/Info.plist" +sed -i".bak" "s/%CFBundleShortVersionString%/${SQUEAK_VERSION_NUMBER}/g" "${CONTENTS_PATH}/Info.plist" +sed -i".bak" "s/%CFBundleVersion%/${IMAGE_BITS} bit/g" "${CONTENTS_PATH}/Info.plist" +sed -i".bak" "s/%SqueakImageName%/${IMAGE_NAME}.image/g" "${CONTENTS_PATH}/Info.plist" +rm -f "${CONTENTS_PATH}/Info.plist.bak" + +if should_codesign; then + do_codesign "${APP_PATH}" # *.app +fi + +compress_into_product_macOS "${APP_PATH}" "${BUNDLE_NAME_MAC}" +reset_build_dir + +end_group diff --git a/prepare_bundle_windows.sh b/prepare_bundle_windows.sh new file mode 100755 index 0000000..b735614 --- /dev/null +++ b/prepare_bundle_windows.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +################################################################################ +# PROJECT: Squeak Bundle Generation +# FILE: prepare_bundle_windows.sh +# CONTENT: Generate bundle for Windows. +# +# AUTHORS: Fabio Niephaus, Hasso Plattner Institute, Potsdam, Germany +# Marcel Taeumel, Hasso Plattner Institute, Potsdam, Germany +################################################################################ + +begin_group "Creating Windows bundle for ${SMALLTALK_VERSION}..." +BUNDLE_NAME_WIN="${IMAGE_NAME}-${VERSION_VM_WIN}-Windows" +export_variable "BUNDLE_NAME_WIN" "${BUNDLE_NAME_WIN}" +BUNDLE_PATH="${BUILD_PATH}/${BUNDLE_NAME_WIN}" + +echo "...creating directories..." +mkdir -p "${BUNDLE_PATH}" + +echo "...copying Windows VM..." +cp -R "${TMP_PATH}/${VM_WIN}/"* "${BUNDLE_PATH}" + +copy_resources "${BUNDLE_PATH}" + +echo "...merging template..." +cp "${AIO_TEMPLATE_PATH}/Squeak.app/Contents/Win32/Squeak.ini" "${BUNDLE_PATH}/" + +echo "...setting permissions..." +chmod +x "${BUNDLE_PATH}/Squeak.exe" + +echo "...applying various patches..." +# Squeak.ini +sed -i".bak" "s/%WindowTitle%/${WINDOW_TITLE}/g" "${BUNDLE_PATH}/Squeak.ini" +rm -f "${BUNDLE_PATH}/Squeak.ini.bak" +# Remove .map files from $BUNDLE_PATH +rm -f "${BUNDLE_PATH}/"*.map + +compress_into_product "${BUNDLE_NAME_WIN}" +reset_build_dir + +end_group diff --git a/prepare_bundles.sh b/prepare_bundles.sh new file mode 100755 index 0000000..2cb706e --- /dev/null +++ b/prepare_bundles.sh @@ -0,0 +1,81 @@ +#!/usr/bin/env bash +################################################################################ +# PROJECT: Squeak Bundle Generation +# FILE: prepare_bundles.sh +# CONTENT: Generate different bundles such as the All-in-One. +# +# REQUIRES: +# SMALLTALK_VERSION ... e.g., Squeak64-trunk or Etoys64-trunk +# SHOULD_CODESIGN ... i.e., true or false +# tmp/Squeak.image +# tmp/Squeak.changes +# tmp/*.sources +# SQUEAK_VERSION ... e.g., Squeak6.0alpha +# SQUEAK_UPDATE ... e.g., 20639 +# IMAGE_BITS ... i.e., 64 or 32 +# OPTIONAL: +# CODESIGN_KEY ... i.e., for unlocking secret files +# CODESIGN_IV ... i.e., for unlocking secret files +# CERT_IDENTITY ... i.e., for signing the bundle +# CERT_PASSWORD ... i.e., for signing the bundle +# NOTARIZATION_USER ... i.e., for distributing the bundle +# NOTARIZATION_PASSWORD i.e., for distributing the bundle +# PROVIDES: +# IMAGE_NAME ... e.g., Squeak6.0alpha-20639-64bit +# product/*.zip +# product/*.dmg +# +# AUTHORS: Fabio Niephaus, Hasso Plattner Institute, Potsdam, Germany +# Marcel Taeumel, Hasso Plattner Institute, Potsdam, Germany +################################################################################ + +set -o errexit + +source "env_vars" +source "helpers.sh" +source "helpers_bundles.sh" + +[[ -z "${SMALLTALK_VERSION}" ]] && exit 2 +[[ -z "${SHOULD_CODESIGN}" ]] && exit 3 + +[[ -z "${SQUEAK_VERSION}" ]] && exit 4 +[[ -z "${SQUEAK_UPDATE}" ]] && exit 5 +[[ -z "${IMAGE_BITS}" ]] && exit 6 + +readonly TEMPLATE_PATH="${HOME_PATH}/templates" +readonly AIO_TEMPLATE_PATH="${TEMPLATE_PATH}/all-in-one" +readonly LIN_TEMPLATE_PATH="${TEMPLATE_PATH}/linux" +readonly MAC_TEMPLATE_PATH="${TEMPLATE_PATH}/macos" +readonly WIN_TEMPLATE_PATH="${TEMPLATE_PATH}/win" + +readonly LOCALE_PATH="${HOME_PATH}/locale" + +readonly VM_VERSIONS="versions.txt" + +if is_etoys; then + readonly SMALLTALK_NAME="Etoys" +else + readonly SMALLTALK_NAME="Squeak" +fi + +source "prepare_image_post.sh" +download_and_extract_all_vms + +if should_codesign; then + source "helpers_codesign.sh" + prepare_codesign +fi + +prepare_image_bundle # Just .image and .changes in an archive +source "prepare_bundle_aio.sh" +source "prepare_bundle_macos.sh" +source "prepare_bundle_linux.sh" +source "prepare_bundle_windows.sh" + +if is_32bit; then + source "prepare_bundle_linux_armv6.sh" +fi + +if should_codesign; then + cleanup_codesign +fi diff --git a/prepare_image.sh b/prepare_image.sh index 2d933b7..a6bc044 100755 --- a/prepare_image.sh +++ b/prepare_image.sh @@ -4,151 +4,72 @@ # FILE: prepare_image.sh # CONTENT: Prepare appropriate base image. # +# REQUIRES: +# SMALLTALK_VERSION ... e.g., Squeak64-trunk +# PROVIDES: +# SQUEAK_VERSION ... e.g., Squeak6.0alpha +# SQUEAK_UPDATE ... e.g., 20639 +# IMAGE_BITS ... i.e., 64 or 32 +# IMAGE_FORMAT ... e.g., 68021 +# tmp/Squeak.image +# tmp/Squeak.changes +# tmp/*.sources +# # AUTHORS: Fabio Niephaus, Hasso Plattner Institute, Potsdam, Germany # Marcel Taeumel, Hasso Plattner Institute, Potsdam, Germany ################################################################################ +set -o errexit + +[[ -z "${SMALLTALK_VERSION}" ]] && exit 2 + +source "env_vars" +source "helpers.sh" + download_and_prepare_files() { print_info "...downloading and extracting image, changes, and sources..." - curl -f -s --retry 3 -o "${TMP_DIR}/base.zip" "${IMAGE_URL}" + curl -f -s --retry 3 -o "${TMP_PATH}/base.zip" "${IMAGE_URL}" - if [[ ! -f "${TMP_DIR}/base.zip" ]]; then + if [[ ! -f "${TMP_PATH}/base.zip" ]]; then echo "Base image not found at ${IMAGE_URL}!" exit 1 fi - unzip -q "${TMP_DIR}/base.zip" -d "${TMP_DIR}/" - mv "${TMP_DIR}/"*.image "${TMP_DIR}/Squeak.image" - mv "${TMP_DIR}/"*.changes "${TMP_DIR}/Squeak.changes" - cp -R "${RELEASE_NOTES_DIR}" "${TMP_DIR}/" - cp "${ICONS_DIR}/balloon.png" "${TMP_DIR}/" - - if is_etoys; then - download_and_prepare_additional_files_for_etoys - fi -} - -download_and_prepare_additional_files_for_etoys() { - travis_fold start main_projects "...preparing etoys main projects..." - for project in "${TRAVIS_BUILD_DIR}/etoys/"*.[0-9]*; do - zip -j "${project}.zip" "${project}"/* - mv "${project}.zip" "${TMP_DIR}/${project##*/}.pr" - done - travis_fold end main_projects - - travis_fold start gallery_projects "...preparing etoys gallery projects..." - mkdir -p "${TMP_DIR}/ExampleEtoys" - for project in "${TRAVIS_BUILD_DIR}/etoys/ExampleEtoys/"*.[0-9]*; do - zip -j "${project}.zip" "${project}"/* - mv "${project}.zip" "${TMP_DIR}/ExampleEtoys/${project##*/}.pr" - done - travis_fold end gallery_projects - - echo "...copying etoys quick guides..." - for language in "${TRAVIS_BUILD_DIR}/etoys/QuickGuides/"*; do - targetdir="${TMP_DIR}/locale/${language##*/}" - mkdir -p "${targetdir}" - cp -R "${language}/QuickGuides" "${targetdir}/" - done + unzip -q "${TMP_PATH}/base.zip" -d "${TMP_PATH}/" + mv "${TMP_PATH}/"*.image "${TMP_PATH}/Squeak.image" + mv "${TMP_PATH}/"*.changes "${TMP_PATH}/Squeak.changes" + cp -R "${RELEASE_NOTES_PATH}" "${TMP_PATH}/" + cp "${ICONS_PATH}/balloon.png" "${TMP_PATH}/" } prepare_image() { - travis_fold start prepare_image "...launching, updating, and configuring Squeak..." + begin_group "...launching, updating, and configuring Squeak..." # Do not use -headless here, otherwise there is a problem with the image's initial dimensions - "${SMALLTALK_VM}" "${TMP_DIR}/Squeak.image" \ - "${TRAVIS_BUILD_DIR}/prepare_image.st" "${TRAVIS_SMALLTALK_VERSION}" - travis_fold end prepare_image - if ! is_file "${VERSION_FILE}"; then - echo "Image preparation failed: version.sh file was not exported." - exit 1 - fi -} - -test_image() { - local ston_config="${SCI_DIR}/default.ston" - - if [[ -f "${SCI_DIR}/${TRAVIS_SMALLTALK_VERSION}.ston" ]]; then - ston_config="${SCI_DIR}/${TRAVIS_SMALLTALK_VERSION}.ston" - fi - - cp "${TMP_DIR}/Squeak.image" "${TMP_DIR}/Test.image" - cp "${TMP_DIR}/Squeak.changes" "${TMP_DIR}/Test.changes" - - travis_fold start test_image "...testing Squeak with ${ston_config}..." - "${SMALLTALK_VM}" -headless "${TMP_DIR}/Test.image" \ - "${TRAVIS_BUILD_DIR}/test_image.st" "${TRAVIS_SMALLTALK_VERSION}" \ - "${SMALLTALK_CI_HOME}" "${ston_config}" \ - || true # Ignore crashes/failures - check_test_status - travis_fold end test_image -} - -check_test_status() { - local test_status_file="build_status.txt" - local build_status - - # Temporarily disable test status check for trunk builds. Remove this check as - # soon as all tests are running in trunk (hopefully soon). - if is_trunk; then - return 0 - fi - - if ! is_file "${TMP_DIR}/${test_status_file}"; then - echo "Build failed before tests were performed correctly." - exit 1 - fi - build_status=$(cat "${TMP_DIR}/${test_status_file}") - if is_nonzero "${build_status}"; then + pushd "${TMP_PATH}" > /dev/null + "${SMALLTALK_VM}" "Squeak.image" \ + "../prepare_image.st" "${SMALLTALK_VERSION}" + popd > /dev/null + end_group + + readonly VERSION_FILEPATH="${TMP_PATH}/version.sh" + if ! is_file "${VERSION_FILEPATH}"; then + print_error "Image preparation failed: version.sh file was not exported." exit 1 + else + export_version_info fi } -rename_and_move_image() { - echo "...copying image files into build dir..." - cp "${TMP_DIR}/Squeak.image" "${BUILD_DIR}/${IMAGE_NAME}.image" - cp "${TMP_DIR}/Squeak.changes" "${BUILD_DIR}/${IMAGE_NAME}.changes" +export_version_info() { + source "${VERSION_FILEPATH}" # version.sh file produced by image + export_variable "SQUEAK_VERSION" "${SQUEAK_VERSION}" + export_variable "SQUEAK_UPDATE" "${SQUEAK_UPDATE}" + export_variable "IMAGE_BITS" "${IMAGE_BITS}" + export_variable "IMAGE_FORMAT" "${IMAGE_FORMAT}" } -prepare_locales() { - travis_fold start install_gettext "...installing gettext..." - - # gettext 0.19.8.1 is preinstalled, see .travis.yml - # brew update - # brew install gettext - - brew link --force gettext - travis_fold end install_gettext - - travis_fold start prepare_translations "...preparing translations and putting them into bundle..." - for language in "${LOCALE_DIR}/"*; do - pushd "${language}" - targetdir="${TMP_DIR}/locale/${language##*/}/LC_MESSAGES" - for f in *.po; do - mkdir -p "${targetdir}" - msgfmt -v -o "${targetdir}/${f%%po}mo" "${f}" || true # ignore translation problems - done - popd - done - travis_fold end prepare_translations -} +print_info "...starting to build ${SMALLTALK_VERSION}..." -print_info "...starting to build ${TRAVIS_SMALLTALK_VERSION}..." +prepare_platform_vm download_and_prepare_files prepare_image -if ! is_etoys; then - test_image -fi - -# prepare locales for Squeak later than 5.0 -if ! is_Squeak_50; then - prepare_locales -fi - -# Source in version.sh file produced by image -source "${VERSION_FILE}" -readonly IMAGE_NAME="${SQUEAK_VERSION}-${SQUEAK_UPDATE}-${IMAGE_BITS}bit" -readonly SQUEAK_VERSION_NUMBER=$(echo "${SQUEAK_VERSION}" | sed "s/^[A-Za-z]*\(.*\)$/\1/") -readonly WINDOW_TITLE="${SMALLTALK_NAME} ${SQUEAK_VERSION_NUMBER} (${IMAGE_BITS} bit)" - -rename_and_move_image -compress "${IMAGE_NAME}" diff --git a/prepare_image.st b/prepare_image.st index 3e52f54..89907f0 100644 --- a/prepare_image.st +++ b/prepare_image.st @@ -68,10 +68,10 @@ releaseBuilder prepareEnvironment. FileStream stdout nextPutAll: 'Exporting version information for deployment...'; cr; flush. FileStream fileNamed: 'version.sh' do: [:strm | strm - nextPutAll: ('SQUEAK_VERSION="{1}"' format: {SystemVersion current version}); lf; - nextPutAll: ('SQUEAK_UPDATE="{1}"' format: {SystemVersion current highestUpdate}); lf; - nextPutAll: ('IMAGE_BITS="{1}"' format: {Smalltalk image wordSize * 8}); lf; - nextPutAll: ('IMAGE_FORMAT="{1}"' format: {Smalltalk image imageFormatVersion}); lf]. + nextPutAll: ('export SQUEAK_VERSION="{1}"' format: {SystemVersion current version}); lf; + nextPutAll: ('export SQUEAK_UPDATE="{1}"' format: {SystemVersion current highestUpdate}); lf; + nextPutAll: ('export IMAGE_BITS="{1}"' format: {Smalltalk image wordSize * 8}); lf; + nextPutAll: ('export IMAGE_FORMAT="{1}"' format: {Smalltalk image imageFormatVersion}); lf]. FileStream stdout nextPutAll: '[DONE]'; cr; flush. releaseBuilder saveAndQuit. diff --git a/prepare_image_post.sh b/prepare_image_post.sh new file mode 100755 index 0000000..fa01021 --- /dev/null +++ b/prepare_image_post.sh @@ -0,0 +1,92 @@ +#!/usr/bin/env bash +################################################################################ +# PROJECT: Squeak Bundle Generation +# FILE: prepare_image_post.sh +# CONTENT: Prepare content around the base image. +# +# REQUIRES: +# SMALLTALK_VERSION ... e.g., Squeak64-trunk +# SQUEAK_VERSION ... e.g., Squeak6.0alpha +# SQUEAK_UPDATE ... e.g., 20639 +# IMAGE_BITS ... i.e., 64 or 32 +# tmp/Squeak.image +# tmp/Squeak.changes +# tmp/*.sources +# PROVIDES: +# IMAGE_NAME ... e.g., Squeak6.0alpha-20639-64bit +# +# AUTHORS: Fabio Niephaus, Hasso Plattner Institute, Potsdam, Germany +# Marcel Taeumel, Hasso Plattner Institute, Potsdam, Germany +################################################################################ + +download_and_prepare_additional_files_for_etoys() { + begin_group "...preparing Etoys main projects..." + for project in "${HOME_PATH}/etoys/"*.[0-9]*; do + zip -j "${project}.zip" "${project}"/* + mv "${project}.zip" "${TMP_PATH}/${project##*/}.pr" + done + end_group + + begin_group "...preparing etoys gallery projects..." + mkdir -p "${TMP_PATH}/ExampleEtoys" + for project in "${HOME_PATH}/etoys/ExampleEtoys/"*.[0-9]*; do + zip -j "${project}.zip" "${project}"/* + mv "${project}.zip" "${TMP_PATH}/ExampleEtoys/${project##*/}.pr" + done + end_group + + echo "...copying etoys quick guides..." + for language in "${HOME_PATH}/etoys/QuickGuides/"*; do + targetdir="${TMP_PATH}/locale/${language##*/}" + mkdir -p "${targetdir}" + cp -R "${language}/QuickGuides" "${targetdir}/" + done +} + +prepare_image_bundle() { + begin_group "Creating .image/.changes bundle for ${SMALLTALK_VERSION}..." + echo "...copying files into build dir..." + cp "${TMP_PATH}/Squeak.image" "${BUILD_PATH}/${IMAGE_NAME}.image" + cp "${TMP_PATH}/Squeak.changes" "${BUILD_PATH}/${IMAGE_NAME}.changes" + compress_into_product "${IMAGE_NAME}" + reset_build_dir + end_group +} + +prepare_locales() { + begin_group "Preparing locales (1/2): Installing gettext..." + brew update + brew install gettext + brew link --force gettext + end_group + + if [[ ! $(type -t msgfmt) ]]; then + mkdir -p "${TMP_PATH}/locale" # Bundle empty locale directory + print_warning "Preparing locales (2/2): Cannot prepare locales because gettext not installed." + return + fi + + begin_group "Preparing locales (2/2): Compiling translations..." + for language in "${LOCALE_PATH}/"*; do + pushd "${language}" + targetdir="${TMP_PATH}/locale/${language##*/}/LC_MESSAGES" + for f in *.po; do + mkdir -p "${targetdir}" + msgfmt -v -o "${targetdir}/${f%%po}mo" "${f}" || true # ignore translation problems + done + popd + done + end_group +} + +if is_etoys; then + download_and_prepare_additional_files_for_etoys +fi + +prepare_locales + +readonly IMAGE_NAME="${SQUEAK_VERSION}-${SQUEAK_UPDATE}-${IMAGE_BITS}bit" +export_variable "IMAGE_NAME" "${IMAGE_NAME}" + +readonly SQUEAK_VERSION_NUMBER=$(echo "${SQUEAK_VERSION}" | sed "s/^[A-Za-z]*\(.*\)$/\1/") +readonly WINDOW_TITLE="${SMALLTALK_NAME} ${SQUEAK_VERSION_NUMBER} (${IMAGE_BITS} bit)" diff --git a/prepare_mac.sh b/prepare_mac.sh deleted file mode 100755 index 5b3305e..0000000 --- a/prepare_mac.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env bash -################################################################################ -# PROJECT: Squeak Bundle Generation -# FILE: prepare_mac.sh -# CONTENT: Generate bundle for macOS. -# -# AUTHORS: Fabio Niephaus, Hasso Plattner Institute, Potsdam, Germany -# Marcel Taeumel, Hasso Plattner Institute, Potsdam, Germany -################################################################################ - -travis_fold start mac_bundle "Creating macOS bundle for ${TRAVIS_SMALLTALK_VERSION}..." -BUNDLE_NAME_MAC="${IMAGE_NAME}-${VERSION_VM_MACOS}-macOS" -BUNDLE_ID_MAC="org.squeak.$(echo ${SQUEAK_VERSION} | tr '[:upper:]' '[:lower:]')-${IMAGE_BITS}bit" -BUNDLE_TARGET_MAC="${PRODUCT_DIR}/${BUNDLE_NAME_MAC}.dmg" -APP_NAME="${IMAGE_NAME}.app" -APP_DIR="${BUILD_DIR}/${APP_NAME}" -CONTENTS_DIR="${APP_DIR}/Contents" -RESOURCES_DIR="${CONTENTS_DIR}/Resources" -VM_MAC_TARGET="${CONTENTS_DIR}/MacOS" - -echo "...copying macOS VM ..." -if is_dir "${TMP_DIR}/${VM_MAC}/Squeak.app"; then - cp -R "${TMP_DIR}/${VM_MAC}/Squeak.app" "${APP_DIR}" -elif is_dir "${TMP_DIR}/${VM_MAC}/CogSpur.app"; then - cp -R "${TMP_DIR}/${VM_MAC}/CogSpur.app" "${APP_DIR}" -else - echo "Unable to locate macOS VM." && exit 1 -fi - -copy_resources "${RESOURCES_DIR}" - -echo "...merging template..." -cp "${AIO_TEMPLATE_DIR}/Squeak.app/Contents/Info.plist" "${CONTENTS_DIR}/" -cp "${ICONS_DIR}/${SMALLTALK_NAME}"*.icns "${RESOURCES_DIR}/" -ENGLISH_DIR="${AIO_TEMPLATE_DIR}/Squeak.app/Contents/Resources/English.lproj" -if ! is_Squeak_50; then - cp "${ENGLISH_DIR}/Credits.rtf" "${RESOURCES_DIR}/English.lproj/" -fi - -echo "...setting permissions..." -chmod +x "${VM_MAC_TARGET}/Squeak" - -echo "...patching Info.plist..." -# Info.plist -sed -i ".bak" "s/%SmalltalkName%/${SMALLTALK_NAME}/g" "${CONTENTS_DIR}/Info.plist" -sed -i ".bak" "s/%CFBundleGetInfoString%/${BUNDLE_NAME_MAC}/g" "${CONTENTS_DIR}/Info.plist" -sed -i ".bak" "s/%CFBundleIdentifier%/${BUNDLE_ID_MAC}/g" "${CONTENTS_DIR}/Info.plist" -sed -i ".bak" "s/%CFBundleName%/${SMALLTALK_NAME}/g" "${CONTENTS_DIR}/Info.plist" -sed -i ".bak" "s/%CFBundleShortVersionString%/${SQUEAK_VERSION_NUMBER}/g" "${CONTENTS_DIR}/Info.plist" -sed -i ".bak" "s/%CFBundleVersion%/${IMAGE_BITS} bit/g" "${CONTENTS_DIR}/Info.plist" -sed -i ".bak" "s/%SqueakImageName%/${IMAGE_NAME}.image/g" "${CONTENTS_DIR}/Info.plist" -rm -f "${CONTENTS_DIR}/Info.plist.bak" - -# Signing the macOS application -codesign_bundle "${APP_DIR}" - -echo "...compressing the bundle for macOS..." -TMP_DMG="temp.dmg" -hdiutil create -size 192m -volname "${BUNDLE_NAME_MAC}" -srcfolder "${APP_DIR}" \ - -fs HFS+ -fsargs "-c c=64,a=16,e=16" -format UDRW -nospotlight "${TMP_DMG}" -DEVICE="$(hdiutil attach -readwrite -noautoopen -nobrowse "${TMP_DMG}" | awk 'NR==1{print$1}')" -VOLUME="$(mount | grep "${DEVICE}" | sed 's/^[^ ]* on //;s/ ([^)]*)$//')" -hdiutil detach "${DEVICE}" -hdiutil convert "${TMP_DMG}" -format UDBZ -imagekey bzip2-level=6 -o "${BUNDLE_TARGET_MAC}" -rm -f "${TMP_DMG}" - -# Signing the DMG -codesign_bundle "${BUNDLE_TARGET_MAC}" - -if is_deployment_branch && ! is_trunk; then - notarize "${BUNDLE_TARGET_MAC}" -fi - -echo "...done." - -travis_fold end mac_bundle diff --git a/prepare_win.sh b/prepare_win.sh deleted file mode 100755 index d6ddb15..0000000 --- a/prepare_win.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env bash -################################################################################ -# PROJECT: Squeak Bundle Generation -# FILE: prepare_win.sh -# CONTENT: Generate bundle for Windows. -# -# AUTHORS: Fabio Niephaus, Hasso Plattner Institute, Potsdam, Germany -# Marcel Taeumel, Hasso Plattner Institute, Potsdam, Germany -################################################################################ - -travis_fold start win_bundle "Creating Windows bundle for ${TRAVIS_SMALLTALK_VERSION}..." -BUNDLE_NAME_WIN="${IMAGE_NAME}-${VERSION_VM_WIN}-Windows" -BUNDLE_DIR="${BUILD_DIR}/${BUNDLE_NAME_WIN}" - -echo "...creating directories..." -mkdir -p "${BUNDLE_DIR}" - -echo "...copying Windows VM..." -cp -R "${TMP_DIR}/${VM_WIN}/" "${BUNDLE_DIR}" - -copy_resources "${BUNDLE_DIR}" - -echo "...merging template..." -cp "${AIO_TEMPLATE_DIR}/Squeak.app/Contents/Win32/Squeak.ini" "${BUNDLE_DIR}/" - -echo "...setting permissions..." -chmod +x "${BUNDLE_DIR}/Squeak.exe" - -echo "...applying various patches..." -# Squeak.ini -sed -i ".bak" "s/%WindowTitle%/${WINDOW_TITLE}/g" "${BUNDLE_DIR}/Squeak.ini" -rm -f "${BUNDLE_DIR}/Squeak.ini.bak" -# Remove .map files from $BUNDLE_DIR -rm -f "${BUNDLE_DIR}/"*.map - -compress "${BUNDLE_NAME_WIN}" - -travis_fold end win_bundle diff --git a/secret.sh b/secret.sh new file mode 100755 index 0000000..18fc575 --- /dev/null +++ b/secret.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +################################################################################ +# PROJECT: Lock and unlock secrets +# FILE: secret.sh +# CONTENT: Encrypt and decrypt files in/to "./secret-*" directories +# to/from ".secret-*.zip.enc" archive +# +# AUTHORS: Marcel Taeumel, Hasso Plattner Institute, Potsdam, Germany +################################################################################ + +set -o errexit + +source env_vars +source helpers.sh + +readonly OP=$1 # lock or unlock +readonly NAME=$2 +readonly KEY=$3 +readonly IV=$4 + +# For example, you can generate KEY and IV in Squeak as follows: +# ((1 to: 128) collect: [:ea | +# (16 atRandom - 1) printStringBase: 16]) join + +case $OP in + lock) + lock_secret $NAME $KEY $IV + ;; + unlock) + unlock_secret $NAME $KEY $IV + ;; + *) + echo "Unknown operation. Use 'lock' or 'unlock'." + exit 1 + ;; +esac diff --git a/smalltalk-ci/Squeak-5.0.ston b/smalltalk-ci/Squeak-5.0.ston deleted file mode 100644 index 32afac5..0000000 --- a/smalltalk-ci/Squeak-5.0.ston +++ /dev/null @@ -1,26 +0,0 @@ -SmalltalkCISpec { - #testing : { - #allTestCases : true, - #defaultTimeout : 10, - #hidePassingTests : true, - #exclude : { - #classes : [ - #AllocationTest, - #BrowserTest, - #ClosureCompilerTest, - #CompilerTest, - #DecompilerTests, - #ExceptionTests, - #FontTest, - #IslandVMTweaksTestCase, - #MCSnapshotBrowserTest, - #PackageDependencyTest, - #SocketTest, - #SqueakSSLTest, - #StringTest, - #TextAttributesScanningTest, - #TraitSystemTest - ] - } - } -} \ No newline at end of file diff --git a/smalltalk-ci/Squeak-5.1.ston b/smalltalk-ci/Squeak-5.1.ston deleted file mode 100644 index a761aad..0000000 --- a/smalltalk-ci/Squeak-5.1.ston +++ /dev/null @@ -1,29 +0,0 @@ -SmalltalkCISpec { - #testing : { - #allTestCases : true, - #defaultTimeout : 10, - #hidePassingTests : true, - #exclude : { - #classes : [ - #BrowserTest, - #BitmapStreamTests, - #ClosureCompilerTest, - #DecompilerTests, - #ExceptionTests, - #FileList2ModalDialogsTest, - #FontTest, - #IslandVMTweaksTestCase, - #LangEnvBugs, - #LocaleTest, - #MVCToolBuilderTests, - #PackageDependencyTest, - #SocketTest, - #SqueakSSLTest, - #StandardSystemFontsTest, - #TestValueWithinFix, - #UnimplementedCallBugz, - #WebClientServerTest - ] - } - } -} \ No newline at end of file diff --git a/smalltalk-ci/Squeak64-5.1.ston b/smalltalk-ci/Squeak64-5.1.ston deleted file mode 100644 index 8a45a09..0000000 --- a/smalltalk-ci/Squeak64-5.1.ston +++ /dev/null @@ -1,31 +0,0 @@ -SmalltalkCISpec { - #testing : { - #allTestCases : true, - #defaultTimeout : 10, - #hidePassingTests : true, - #exclude : { - #classes : [ - #AllocationTest, - #BrowserTest, - #BitmapStreamTests, - #ClosureCompilerTest, - #DecompilerTests, - #ExceptionTests, - #FileList2ModalDialogsTest, - #FontTest, - #IntegerArrayTest, - #IslandVMTweaksTestCase, - #LangEnvBugs, - #LocaleTest, - #MVCToolBuilderTests, - #PackageDependencyTest, - #SocketTest, - #SqueakSSLTest, - #StandardSystemFontsTest, - #TestValueWithinFix, - #UnimplementedCallBugz, - #WebClientServerTest - ] - } - } -} \ No newline at end of file diff --git a/smalltalk-ci/gha-support.cs b/smalltalk-ci/gha-support.cs new file mode 100644 index 0000000..3d3e11f --- /dev/null +++ b/smalltalk-ci/gha-support.cs @@ -0,0 +1 @@ +'From Squeak6.0alpha of 21 September 2021 [latest update: #20638] on 22 September 2021 at 2:03 pm'! !SCITestReporterStdout methodsFor: 'printing' stamp: 'mt 9/22/2021 10:37'! printDeprecationWarnings SmalltalkCI deprecationWarnings ifNotEmpty: [ self newLine; printFold: 'deprecation_warnings' action: 'start'; setModeBoldRed; print: 'smalltalkCI Deprecation Warnings'; resetMode; newLine. SmalltalkCI deprecationWarnings do: [ :each | self print: ' - ', each; newLine ]. self printFold: 'deprecation_warnings' action: 'end' ].! ! !SCITestReporterStdout methodsFor: 'printing' stamp: 'mt 9/22/2021 13:27'! printException: aResult self newLine; printFold: aResult foldName action: 'start'; setModeBold; print: (aResult ansiTitleContractedTo: 70); newLine; setModeBold; print: aResult testError asString; resetMode. aResult stack ifNotNil: [ self newLine; print: aResult stack; resetMode ]. self newLine; printFold: aResult foldName action: 'end'! ! !SCITestReporterStdout methodsFor: 'printing' stamp: 'mt 9/22/2021 10:37'! printFold: foldName action: action SmalltalkCI isTravisBuild ifTrue: [ ^ self print: (SmalltalkCI travisFold: foldName action: action) ]. SmalltalkCI isGitHubActionBuild ifTrue: [ ^ action = 'start' ifTrue: [ self print: (SmalltalkCI ghaBeginGroup: foldName) ] ifFalse: [ self print: SmalltalkCI ghaEndGroup ] ].! ! !SCITestReporterStdout methodsFor: 'printing' stamp: 'mt 9/22/2021 14:02'! printNotPassingResults | title | title := (runner erroredTests + runner failedTests) asString, ' tests did not pass:'. self printBanner: title color: SmalltalkCI ansiRed. runner results keysAndValuesDo: [ :class :results | | notPassing | notPassing := results select: [ :result | result passed not ]. notPassing ifNotEmpty: [ self newLine; printTitle: class asString. notPassing do: [ :result | self printException: result ] ] ]. (SmalltalkCI isTravisBuild or: [SmalltalkCI isGitHubActionBuild]) ifFalse: [ self printNotPassingSummary ]! ! !SCITestReporterStdout methodsFor: 'printing' stamp: 'mt 9/22/2021 14:01'! printNotPassingSummary self newLine; printBanner: 'Summary' color: SmalltalkCI ansiRed. runner results keysAndValuesDo: [ :class :results | | notPassing | notPassing := results select: [ :result | result passed not ]. notPassing ifNotEmpty: [ self newLine; printTitle: class asString. notPassing do: [ :result | self newLine; print: result ansiTitle ] ] ]! ! !SCITestReporterStdout methodsFor: 'printing' stamp: 'mt 9/22/2021 13:28'! printPass: aResult self newLine; print: aResult ansiTitle! ! !SCITestReporterStdout methodsFor: 'printing' stamp: 'mt 9/22/2021 14:02'! printPassingResults | title | self newLine; printFold: 'passing_tests' action: 'start'. title := '(', runner passingTests asString, ' tests passed)'. self print: title; newLine. [ runner results keysAndValuesDo: [ :class :results | | passing | passing := results select: [ :result | result passed ]. passing ifNotEmpty: [ self newLine; printTitle: class asString. passing do: [ :result | self printPass: result ] ] ] ] ensure: [ self printFold: 'passing_tests' action: 'end' ]! ! !SCITestReporterStdout methodsFor: 'printing' stamp: 'mt 9/22/2021 13:25'! printTitle: aTitle self setModeBold; newLine; print: aTitle; resetMode! ! !SmalltalkCI class methodsFor: 'helpers' stamp: 'mt 9/22/2021 10:18'! isGitHubActionBuild "^ (self getEnv: 'CI') = 'true'" ^ (self getEnv: 'GITHUB_ACTION') notNil! ! !SmalltalkCI class methodsFor: 'folding' stamp: 'mt 9/22/2021 13:22'! ghaBeginGroup: title ^ '::group::', title! ! !SmalltalkCI class methodsFor: 'folding' stamp: 'mt 9/22/2021 13:22'! ghaEndGroup ^ '::endgroup::'! ! !SmalltalkCI class methodsFor: 'folding' stamp: 'mt 9/22/2021 10:28'! ghaGroup: aTitle block: aBlock self ghaGroup: aTitle on: self stdout block: aBlock! ! !SmalltalkCI class methodsFor: 'folding' stamp: 'mt 9/22/2021 10:26'! ghaGroup: aTitle on: aStream block: aBlock aStream nextPutAll: (self ghaBeginGroup: aTitle); flush. [ aBlock value ] ensure: [aStream nextPutAll: self ghaEndGroup; flush ]! ! !SmalltalkCI class methodsFor: 'folding' stamp: 'mt 9/22/2021 10:31'! stage: stageTitle id: anID block: aBlock self isTravisBuild ifTrue: [ ^ self travisFold: stageTitle id: anID block: aBlock ]. self isGitHubActionBuild ifTrue: [ ^ self ghaGroup: stageTitle block: aBlock ]. self fold: stageTitle block: aBlock.! ! !SmalltalkCISpec class methodsFor: 'defaults' stamp: 'mt 9/22/2021 10:40'! defaultName | result | result := SmalltalkCI smalltalkSelection ifNil: [ 'unknown' ]. SmalltalkCI isTravisBuild ifTrue: [ ^ result, ' on Travis CI (', (SmalltalkCI getEnv: 'TRAVIS_JOB_NUMBER') asString, ')' ]. SmalltalkCI isAppVeyorBuild ifTrue: [ ^ result, ' on AppVeyor (', (SmalltalkCI getEnv: 'APPVEYOR_JOB_NAME') asString, ')' ]. SmalltalkCI isGitLabCIBuild ifTrue: [ ^ result, ' on GitLab CI (', (SmalltalkCI getEnv: 'CI_PIPELINE_ID') asString, '.', (SmalltalkCI getEnv: 'CI_JOB_ID') asString, ')' ]. SmalltalkCI isGitHubActionBuild ifTrue: [ ^ result, ' via GitHub Action (', (SmalltalkCI getEnv: 'GITHUB_JOB') asString, '.', (SmalltalkCI getEnv: 'GITHUB_ACTION') asString, ')' ]. ^ result! ! SCITestReporterStdout removeSelector: #printTravisFold:action:! \ No newline at end of file diff --git a/templates/all-in-one/squeak.sh b/templates/all-in-one/squeak.sh index 623b0aa..476e8b7 100644 --- a/templates/all-in-one/squeak.sh +++ b/templates/all-in-one/squeak.sh @@ -1,17 +1,17 @@ #!/usr/bin/env bash # File: squeak.sh (All-in-One version) # Authors: Bert Freudenberg, Paul DeBruicker, Craig Latta, Chris Muller, -# Fabio Niephaus -# Version: 2.2 -# Date: 2020/03/31 +# Fabio Niephaus, Marcel Taeumel +# Version: 2.2.1 +# Date: 2021/09/25 # Description: Script to run Squeak from the all-in-one app structure # (based on Etoys-To-Go) -APP_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/%APP_NAME%" && pwd )" -IMAGE="${APP_DIR}/Contents/Resources/%SqueakImageName%" +APP_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )/%APP_NAME%" && pwd )" +IMAGE="${APP_PATH}/Contents/Resources/%SqueakImageName%" IMAGE_BITS="%IMAGE_BITS%" CPU="$(uname -m)" -CONF_FILE="/etc/security/limits.d/squeak.conf" +CONF_FILEPATH="/etc/security/limits.d/squeak.conf" showerror() { if [[ -n "${DISPLAY}" ]] && [[ -x "$(which kdialog 2>/dev/null)" ]]; then @@ -56,21 +56,21 @@ ensure_kernel() { exit 1 fi - # Check for $CONF_FILE on systems with Linux kernel earlier than 4.x.x + # Check for $CONF_FILEPATH on systems with Linux kernel earlier than 4.x.x if [[ "${major}" -lt "4" ]]; then ensure_conf_file fi } -# Ensure that the $CONF_FILE configuration file exists and help to create one +# Ensure that the $CONF_FILEPATH configuration file exists and help to create one ensure_conf_file() { local user_input - if ! [[ -f "${CONF_FILE}" ]]; then - read -p "${CONF_FILE} is missing. Do you want to create one? + if ! [[ -f "${CONF_FILEPATH}" ]]; then + read -p "${CONF_FILEPATH} is missing. Do you want to create one? This operation requires sudo permissions. (y/N): " user_input if [[ "${user_input}" = "y" ]]; then echo "You may be asked to enter your password..." - sudo tee -a "${CONF_FILE}" > /dev/null < /dev/null <] [ *.image [ ... ]] @@ -12,7 +12,7 @@ ROOT=$(cd -P $(dirname "$0"); pwd) APP=$(basename "$0" .sh) readonly APP_NAME=${APP^} # first letter uppercase -CONF_FILE="/etc/security/limits.d/${APP}.conf" +CONF_FILEPATH="/etc/security/limits.d/${APP}.conf" OS=$(uname -s) CPU=$(uname -m) case "${CPU}" in @@ -80,21 +80,21 @@ ensure_linux_kernel() { exit 1 fi - # Check for $CONF_FILE on systems with Linux kernel earlier than 4.x.x + # Check for $CONF_FILEPATH on systems with Linux kernel earlier than 4.x.x if [[ "${major}" -lt "4" ]]; then ensure_conf_file fi } -# Ensure that the $CONF_FILE configuration file exists and help to create one +# Ensure that the $CONF_FILEPATH configuration file exists and help to create one ensure_conf_file() { local user_input - if ! [[ -f "${CONF_FILE}" ]]; then - read -p "${CONF_FILE} is missing. Do you want to create one? + if ! [[ -f "${CONF_FILEPATH}" ]]; then + read -p "${CONF_FILEPATH} is missing. Do you want to create one? This operation requires sudo permissions. (y/N): " user_input if [[ "${user_input}" = "y" ]]; then echo "You may be asked to enter your password..." - sudo tee -a "${CONF_FILE}" > /dev/null < /dev/null < /dev/null + "${SMALLTALK_VM}" -headless "Test.image" \ + "../test_image.st" "${SMALLTALK_VERSION}" \ + "../smalltalk-ci" "${ston_config}" \ + || true # Ignore crashes/failures + popd > /dev/null + check_test_status + end_group +} + +check_test_status() { + local test_status_file="build_status.txt" + local build_status + + if ! is_file "${TMP_PATH}/${test_status_file}"; then + print_error "...build failed before tests were performed correctly!" + exit 1 + fi + build_status=$(cat "${TMP_PATH}/${test_status_file}") + if [[ ! -z "${build_status}" ]]; then + # Note that build_status is not expected to be "[successful]" but empty on success + print_warning "...all tests were performed correctly but they did not all pass." + exit 1 + fi +} + +prepare_platform_vm +test_image diff --git a/test_image.st b/test_image.st index f19ce01..6427a7a 100644 --- a/test_image.st +++ b/test_image.st @@ -1,31 +1,34 @@ -| smalltalkVersion smalltalkCIDir stonConfig monitor | -smalltalkVersion := (Smalltalk argumentAt: 1) ifNil: ['']. -smalltalkCIDir := Smalltalk argumentAt: 2. -stonConfig := Smalltalk argumentAt: 3. - -"Ensure FileStream stdout is open" -FileStream startUp: true. - -monitor := [ [ - FileStream stdout nextPutAll: '.'. - (Delay forMilliseconds: 5000) wait] repeat ] forkAt: 75. - -"# Install smalltalkCI ========================================================" - -"Metacello will automatically be bootstrapped via MetacelloStub" -[ Metacello new - baseline: 'SmalltalkCI'; - repository: 'filetree://', smalltalkCIDir , '/repository'; - onConflict: [:ex | ex pass]; - load ] on: Warning do: [:w | w resume ]. - -monitor terminate. -monitor := nil. - -FileStream stdout closed ifTrue: [ FileStream startUp: true ]. - -(Smalltalk at: #SmalltalkCI) test: stonConfig named: 'Squeak SUnit Tests'. - -"Currently not reached, because SmalltalkCI>>test: closes image already" -FileStream stdout nextPutAll: 'Closing image after testing...'; cr; flush. -Smalltalk snapshot: false andQuit: true. +| smalltalkVersion smalltalkCIDir stonConfig monitor | +smalltalkVersion := (Smalltalk argumentAt: 1) ifNil: ['']. +smalltalkCIDir := (FileDirectory default on: (Smalltalk argumentAt: 2)) fullName. +stonConfig := Smalltalk argumentAt: 3. + +"Ensure FileStream stdout is open" +FileStream startUp: true. + +monitor := [ [ + FileStream stdout nextPutAll: '.'. + (Delay forMilliseconds: 5000) wait] repeat ] forkAt: 75. + +"# Install smalltalkCI ========================================================" + +"Metacello will automatically be bootstrapped via MetacelloStub" +[ Metacello new + baseline: 'SmalltalkCI'; + repository: 'filetree://', smalltalkCIDir , '/repository'; + onConflict: [:ex | ex pass]; + load ] on: Warning do: [:w | w resume ]. + +"Patch smalltalkCI to support GitHub Actions" +FileStream fileIn: smalltalkCIDir, FileDirectory slash, 'gha-support.cs'. + +monitor terminate. +monitor := nil. + +FileStream stdout closed ifTrue: [ FileStream startUp: true ]. + +(Smalltalk at: #SmalltalkCI) test: stonConfig named: 'Squeak SUnit Tests'. + +"Currently not reached, because SmalltalkCI>>test: closes image already" +FileStream stdout nextPutAll: 'Closing image after testing...'; cr; flush. +Smalltalk snapshot: false andQuit: true.