From dd4b0897b41969f724a6ac609c1bc7459d11f3d9 Mon Sep 17 00:00:00 2001 From: rina Date: Mon, 7 Jul 2025 12:13:03 +1000 Subject: [PATCH 1/9] add mill-version --- .gitattributes | 2 + offlineASL-scala/.mill-version | 1 + offlineASL-scala/build.sc | 21 +-- offlineASL-scala/mill | 327 +++++++++++++++++++++++++++++++++ offlineASL-scala/mill.bat | 296 +++++++++++++++++++++++++++++ 5 files changed, 635 insertions(+), 12 deletions(-) create mode 100644 offlineASL-scala/.mill-version create mode 100755 offlineASL-scala/mill create mode 100644 offlineASL-scala/mill.bat diff --git a/.gitattributes b/.gitattributes index 77617ab4..1745a091 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,3 +3,5 @@ *.t linguist-vendored *.asl linguist-vendored dune.generated linguist-generated +mill linguist-vendored +mill.bat linguist-vendored diff --git a/offlineASL-scala/.mill-version b/offlineASL-scala/.mill-version new file mode 100644 index 00000000..d0834a7f --- /dev/null +++ b/offlineASL-scala/.mill-version @@ -0,0 +1 @@ +0.12.14 diff --git a/offlineASL-scala/build.sc b/offlineASL-scala/build.sc index bffc3304..4592a687 100644 --- a/offlineASL-scala/build.sc +++ b/offlineASL-scala/build.sc @@ -1,23 +1,20 @@ import mill._, scalalib._ - - - object lifter extends ScalaModule { - def scalaVersion = "3.3.1" + def scalaVersion = "3.3.6" } object main extends ScalaModule { - def scalaVersion = "3.3.1" + def scalaVersion = "3.3.6" - def moduleDeps = Seq(lifter) + def moduleDeps = Seq(lifter) - def ivyDeps = Agg( - ivy"com.lihaoyi::mainargs:0.6.2", - ivy"com.lihaoyi::sourcecode:0.3.0" - ) + def ivyDeps = Agg( + ivy"com.lihaoyi::mainargs:0.6.2", + ivy"com.lihaoyi::sourcecode:0.3.0" + ) - def mainClass = Some("main.Main") + def mainClass = Some("main.Main") - } +} diff --git a/offlineASL-scala/mill b/offlineASL-scala/mill new file mode 100755 index 00000000..555d7fc7 --- /dev/null +++ b/offlineASL-scala/mill @@ -0,0 +1,327 @@ +#!/usr/bin/env sh + +# This is a wrapper script, that automatically selects or downloads Mill from Maven Central or GitHub release pages. +# +# This script determines the Mill version to use by trying these sources +# - env-variable `MILL_VERSION` +# - local file `.mill-version` +# - local file `.config/mill-version` +# - `mill-version` from YAML fronmatter of current buildfile +# - if accessible, find the latest stable version available on Maven Central (https://repo1.maven.org/maven2) +# - env-variable `DEFAULT_MILL_VERSION` +# +# If a version has the suffix '-native' a native binary will be used. +# If a version has the suffix '-jvm' an executable jar file will be used, requiring an already installed Java runtime. +# If no such suffix is found, the script will pick a default based on version and platform. +# +# Once a version was determined, it tries to use either +# - a system-installed mill, if found and it's version matches +# - an already downloaded version under ~/.cache/mill/download +# +# If no working mill version was found on the system, +# this script downloads a binary file from Maven Central or Github Pages (this is version dependent) +# into a cache location (~/.cache/mill/download). +# +# Mill Project URL: https://github.com/com-lihaoyi/mill +# Script Version: 1.0.0-M1-49-ac90e3 +# +# If you want to improve this script, please also contribute your changes back! +# This script was generated from: dist/scripts/src/mill.sh +# +# Licensed under the Apache License, Version 2.0 + +set -e + +if [ -z "${DEFAULT_MILL_VERSION}" ] ; then + DEFAULT_MILL_VERSION=0.12.14 +fi + + +if [ -z "${GITHUB_RELEASE_CDN}" ] ; then + GITHUB_RELEASE_CDN="" +fi + + +MILL_REPO_URL="https://github.com/com-lihaoyi/mill" + +if [ -z "${CURL_CMD}" ] ; then + CURL_CMD=curl +fi + +# Explicit commandline argument takes precedence over all other methods +if [ "$1" = "--mill-version" ] ; then + echo "The --mill-version option is no longer supported." 1>&2 +fi + +MILL_BUILD_SCRIPT="" + +if [ -f "build.mill" ] ; then + MILL_BUILD_SCRIPT="build.mill" +elif [ -f "build.mill.scala" ] ; then + MILL_BUILD_SCRIPT="build.mill.scala" +elif [ -f "build.sc" ] ; then + MILL_BUILD_SCRIPT="build.sc" +fi + +# Please note, that if a MILL_VERSION is already set in the environment, +# We reuse it's value and skip searching for a value. + +# If not already set, read .mill-version file +if [ -z "${MILL_VERSION}" ] ; then + if [ -f ".mill-version" ] ; then + MILL_VERSION="$(tr '\r' '\n' < .mill-version | head -n 1 2> /dev/null)" + elif [ -f ".config/mill-version" ] ; then + MILL_VERSION="$(tr '\r' '\n' < .config/mill-version | head -n 1 2> /dev/null)" + elif [ -n "${MILL_BUILD_SCRIPT}" ] ; then + MILL_VERSION="$(cat ${MILL_BUILD_SCRIPT} | grep '//[|] *mill-version: *' | sed 's;//| *mill-version: *;;')" + fi +fi + +MILL_USER_CACHE_DIR="${XDG_CACHE_HOME:-${HOME}/.cache}/mill" + +if [ -z "${MILL_DOWNLOAD_PATH}" ] ; then + MILL_DOWNLOAD_PATH="${MILL_USER_CACHE_DIR}/download" +fi + +# If not already set, try to fetch newest from Github +if [ -z "${MILL_VERSION}" ] ; then + # TODO: try to load latest version from release page + echo "No mill version specified." 1>&2 + echo "You should provide a version via a '//| mill-version: ' comment or a '.mill-version' file." 1>&2 + + mkdir -p "${MILL_DOWNLOAD_PATH}" + LANG=C touch -d '1 hour ago' "${MILL_DOWNLOAD_PATH}/.expire_latest" 2>/dev/null || ( + # we might be on OSX or BSD which don't have -d option for touch + # but probably a -A [-][[hh]mm]SS + touch "${MILL_DOWNLOAD_PATH}/.expire_latest"; touch -A -010000 "${MILL_DOWNLOAD_PATH}/.expire_latest" + ) || ( + # in case we still failed, we retry the first touch command with the intention + # to show the (previously suppressed) error message + LANG=C touch -d '1 hour ago' "${MILL_DOWNLOAD_PATH}/.expire_latest" + ) + + # POSIX shell variant of bash's -nt operator, see https://unix.stackexchange.com/a/449744/6993 + # if [ "${MILL_DOWNLOAD_PATH}/.latest" -nt "${MILL_DOWNLOAD_PATH}/.expire_latest" ] ; then + if [ -n "$(find -L "${MILL_DOWNLOAD_PATH}/.latest" -prune -newer "${MILL_DOWNLOAD_PATH}/.expire_latest")" ]; then + # we know a current latest version + MILL_VERSION=$(head -n 1 "${MILL_DOWNLOAD_PATH}"/.latest 2> /dev/null) + fi + + if [ -z "${MILL_VERSION}" ] ; then + # we don't know a current latest version + echo "Retrieving latest mill version ..." 1>&2 + LANG=C ${CURL_CMD} -s -i -f -I ${MILL_REPO_URL}/releases/latest 2> /dev/null | grep --ignore-case Location: | sed s'/^.*tag\///' | tr -d '\r\n' > "${MILL_DOWNLOAD_PATH}/.latest" + MILL_VERSION=$(head -n 1 "${MILL_DOWNLOAD_PATH}"/.latest 2> /dev/null) + fi + + if [ -z "${MILL_VERSION}" ] ; then + # Last resort + MILL_VERSION="${DEFAULT_MILL_VERSION}" + echo "Falling back to hardcoded mill version ${MILL_VERSION}" 1>&2 + else + echo "Using mill version ${MILL_VERSION}" 1>&2 + fi +fi + +MILL_NATIVE_SUFFIX="-native" +MILL_JVM_SUFFIX="-jvm" +FULL_MILL_VERSION=$MILL_VERSION +ARTIFACT_SUFFIX="" +set_artifact_suffix(){ + if [ "$(expr substr $(uname -s) 1 5 2>/dev/null)" = "Linux" ]; then + if [ "$(uname -m)" = "aarch64" ]; then + ARTIFACT_SUFFIX="-native-linux-aarch64" + else + ARTIFACT_SUFFIX="-native-linux-amd64" + fi + elif [ "$(uname)" = "Darwin" ]; then + if [ "$(uname -m)" = "arm64" ]; then + ARTIFACT_SUFFIX="-native-mac-aarch64" + else + ARTIFACT_SUFFIX="-native-mac-amd64" + fi + else + echo "This native mill launcher supports only Linux and macOS." 1>&2 + exit 1 + fi +} + +case "$MILL_VERSION" in + *"$MILL_NATIVE_SUFFIX") + MILL_VERSION=${MILL_VERSION%"$MILL_NATIVE_SUFFIX"} + set_artifact_suffix + ;; + + *"$MILL_JVM_SUFFIX") + MILL_VERSION=${MILL_VERSION%"$MILL_JVM_SUFFIX"} + ;; + + *) + case "$MILL_VERSION" in + 0.1.*) ;; + 0.2.*) ;; + 0.3.*) ;; + 0.4.*) ;; + 0.5.*) ;; + 0.6.*) ;; + 0.7.*) ;; + 0.8.*) ;; + 0.9.*) ;; + 0.10.*) ;; + 0.11.*) ;; + 0.12.*) ;; + *) + set_artifact_suffix + esac + ;; +esac + +MILL="${MILL_DOWNLOAD_PATH}/$MILL_VERSION$ARTIFACT_SUFFIX" + +try_to_use_system_mill() { + if [ "$(uname)" != "Linux" ]; then + return 0 + fi + + MILL_IN_PATH="$(command -v mill || true)" + + if [ -z "${MILL_IN_PATH}" ]; then + return 0 + fi + + SYSTEM_MILL_FIRST_TWO_BYTES=$(head --bytes=2 "${MILL_IN_PATH}") + if [ "${SYSTEM_MILL_FIRST_TWO_BYTES}" = "#!" ]; then + # MILL_IN_PATH is (very likely) a shell script and not the mill + # executable, ignore it. + return 0 + fi + + SYSTEM_MILL_PATH=$(readlink -e "${MILL_IN_PATH}") + SYSTEM_MILL_SIZE=$(stat --format=%s "${SYSTEM_MILL_PATH}") + SYSTEM_MILL_MTIME=$(stat --format=%y "${SYSTEM_MILL_PATH}") + + if [ ! -d "${MILL_USER_CACHE_DIR}" ]; then + mkdir -p "${MILL_USER_CACHE_DIR}" + fi + + SYSTEM_MILL_INFO_FILE="${MILL_USER_CACHE_DIR}/system-mill-info" + if [ -f "${SYSTEM_MILL_INFO_FILE}" ]; then + parseSystemMillInfo() { + LINE_NUMBER="${1}" + # Select the line number of the SYSTEM_MILL_INFO_FILE, cut the + # variable definition in that line in two halves and return + # the value, and finally remove the quotes. + sed -n "${LINE_NUMBER}p" "${SYSTEM_MILL_INFO_FILE}" |\ + cut -d= -f2 |\ + sed 's/"\(.*\)"/\1/' + } + + CACHED_SYSTEM_MILL_PATH=$(parseSystemMillInfo 1) + CACHED_SYSTEM_MILL_VERSION=$(parseSystemMillInfo 2) + CACHED_SYSTEM_MILL_SIZE=$(parseSystemMillInfo 3) + CACHED_SYSTEM_MILL_MTIME=$(parseSystemMillInfo 4) + + if [ "${SYSTEM_MILL_PATH}" = "${CACHED_SYSTEM_MILL_PATH}" ] \ + && [ "${SYSTEM_MILL_SIZE}" = "${CACHED_SYSTEM_MILL_SIZE}" ] \ + && [ "${SYSTEM_MILL_MTIME}" = "${CACHED_SYSTEM_MILL_MTIME}" ]; then + if [ "${CACHED_SYSTEM_MILL_VERSION}" = "${MILL_VERSION}" ]; then + MILL="${SYSTEM_MILL_PATH}" + return 0 + else + return 0 + fi + fi + fi + + SYSTEM_MILL_VERSION=$(${SYSTEM_MILL_PATH} --version | head -n1 | sed -n 's/^Mill.*version \(.*\)/\1/p') + + cat < "${SYSTEM_MILL_INFO_FILE}" +CACHED_SYSTEM_MILL_PATH="${SYSTEM_MILL_PATH}" +CACHED_SYSTEM_MILL_VERSION="${SYSTEM_MILL_VERSION}" +CACHED_SYSTEM_MILL_SIZE="${SYSTEM_MILL_SIZE}" +CACHED_SYSTEM_MILL_MTIME="${SYSTEM_MILL_MTIME}" +EOF + + if [ "${SYSTEM_MILL_VERSION}" = "${MILL_VERSION}" ]; then + MILL="${SYSTEM_MILL_PATH}" + fi +} +try_to_use_system_mill + +# If not already downloaded, download it +if [ ! -s "${MILL}" ] || [ "$MILL_TEST_DRY_RUN_LAUNCHER_SCRIPT" = "1" ] ; then + case $MILL_VERSION in + 0.0.* | 0.1.* | 0.2.* | 0.3.* | 0.4.* ) + DOWNLOAD_SUFFIX="" + DOWNLOAD_FROM_MAVEN=0 + ;; + 0.5.* | 0.6.* | 0.7.* | 0.8.* | 0.9.* | 0.10.* | 0.11.0-M* ) + DOWNLOAD_SUFFIX="-assembly" + DOWNLOAD_FROM_MAVEN=0 + ;; + *) + DOWNLOAD_SUFFIX="-assembly" + DOWNLOAD_FROM_MAVEN=1 + ;; + esac + case $MILL_VERSION in + 0.12.0 | 0.12.1 | 0.12.2 | 0.12.3 | 0.12.4 | 0.12.5 | 0.12.6 | 0.12.7 | 0.12.8 | 0.12.9 | 0.12.10 | 0.12.11 ) + DOWNLOAD_EXT="jar" + ;; + 0.12.* ) + DOWNLOAD_EXT="exe" + ;; + 0.* ) + DOWNLOAD_EXT="jar" + ;; + *) + DOWNLOAD_EXT="exe" + ;; + esac + + DOWNLOAD_FILE=$(mktemp mill.XXXXXX) + if [ "$DOWNLOAD_FROM_MAVEN" = "1" ] ; then + DOWNLOAD_URL="https://repo1.maven.org/maven2/com/lihaoyi/mill-dist${ARTIFACT_SUFFIX}/${MILL_VERSION}/mill-dist${ARTIFACT_SUFFIX}-${MILL_VERSION}.${DOWNLOAD_EXT}" + else + MILL_VERSION_TAG=$(echo "$MILL_VERSION" | sed -E 's/([^-]+)(-M[0-9]+)?(-.*)?/\1\2/') + DOWNLOAD_URL="${GITHUB_RELEASE_CDN}${MILL_REPO_URL}/releases/download/${MILL_VERSION_TAG}/${MILL_VERSION}${DOWNLOAD_SUFFIX}" + unset MILL_VERSION_TAG + fi + + if [ "$MILL_TEST_DRY_RUN_LAUNCHER_SCRIPT" = "1" ] ; then + echo $DOWNLOAD_URL + echo $MILL + exit 0 + fi + # TODO: handle command not found + echo "Downloading mill ${MILL_VERSION} from ${DOWNLOAD_URL} ..." 1>&2 + ${CURL_CMD} -f -L -o "${DOWNLOAD_FILE}" "${DOWNLOAD_URL}" + chmod +x "${DOWNLOAD_FILE}" + mkdir -p "${MILL_DOWNLOAD_PATH}" + mv "${DOWNLOAD_FILE}" "${MILL}" + + unset DOWNLOAD_FILE + unset DOWNLOAD_SUFFIX +fi + +if [ -z "$MILL_MAIN_CLI" ] ; then + MILL_MAIN_CLI="${0}" +fi + +MILL_FIRST_ARG="" +if [ "$1" = "--bsp" ] || [ "$1" = "-i" ] || [ "$1" = "--interactive" ] || [ "$1" = "--no-server" ] || [ "$1" = "--repl" ] || [ "$1" = "--help" ] ; then + # Need to preserve the first position of those listed options + MILL_FIRST_ARG=$1 + shift +fi + +unset MILL_DOWNLOAD_PATH +unset MILL_OLD_DOWNLOAD_PATH +unset OLD_MILL +unset MILL_VERSION +unset MILL_REPO_URL + +# -D mill.main.cli is for compatibility with Mill 0.10.9 - 0.13.0-M2 +# We don't quote MILL_FIRST_ARG on purpose, so we can expand the empty value without quotes +# shellcheck disable=SC2086 +exec "${MILL}" $MILL_FIRST_ARG -D "mill.main.cli=${MILL_MAIN_CLI}" "$@" diff --git a/offlineASL-scala/mill.bat b/offlineASL-scala/mill.bat new file mode 100644 index 00000000..85f9605b --- /dev/null +++ b/offlineASL-scala/mill.bat @@ -0,0 +1,296 @@ +@echo off + +rem This is a wrapper script, that automatically selects or downloads Mill from Maven Central or GitHub release pages. +rem +rem This script determines the Mill version to use by trying these sources +rem - env-variable `MILL_VERSION` +rem - local file `.mill-version` +rem - local file `.config/mill-version` +rem - `mill-version` from YAML fronmatter of current buildfile +rem - if accessible, find the latest stable version available on Maven Central (https://repo1.maven.org/maven2) +rem - env-variable `DEFAULT_MILL_VERSION` +rem +rem If a version has the suffix '-native' a native binary will be used. +rem If a version has the suffix '-jvm' an executable jar file will be used, requiring an already installed Java runtime. +rem If no such suffix is found, the script will pick a default based on version and platform. +rem +rem Once a version was determined, it tries to use either +rem - a system-installed mill, if found and it's version matches +rem - an already downloaded version under %USERPROFILE%\.mill\download +rem +rem If no working mill version was found on the system, +rem this script downloads a binary file from Maven Central or Github Pages (this is version dependent) +rem into a cache location (%USERPROFILE%\.mill\download). +rem +rem Mill Project URL: https://github.com/com-lihaoyi/mill +rem Script Version: 1.0.0-M1-49-ac90e3 +rem +rem If you want to improve this script, please also contribute your changes back! +rem This script was generated from: dist/scripts/src/mill.bat +rem +rem Licensed under the Apache License, Version 2.0 + +rem setlocal seems to be unavailable on Windows 95/98/ME +rem but I don't think we need to support them in 2019 +setlocal enabledelayedexpansion + +if [!DEFAULT_MILL_VERSION!]==[] ( set "DEFAULT_MILL_VERSION=0.12.10" ) + +if [!MILL_GITHUB_RELEASE_CDN!]==[] ( set "MILL_GITHUB_RELEASE_CDN=" ) + +if [!MILL_MAIN_CLI!]==[] ( set "MILL_MAIN_CLI=%~f0" ) + +set "MILL_REPO_URL=https://github.com/com-lihaoyi/mill" + +SET MILL_BUILD_SCRIPT= + +if exist "build.mill" ( + set MILL_BUILD_SCRIPT=build.mill +) else ( + if exist "build.mill.scala" ( + set MILL_BUILD_SCRIPT=build.mill.scala + ) else ( + if exist "build.sc" ( + set MILL_BUILD_SCRIPT=build.sc + ) else ( + rem no-op + ) + ) +) + +if [!MILL_VERSION!]==[] ( + if exist .mill-version ( + set /p MILL_VERSION=<.mill-version + ) else ( + if exist .config\mill-version ( + set /p MILL_VERSION=<.config\mill-version + ) else ( + if not "%MILL_BUILD_SCRIPT%"=="" ( + for /f "tokens=1-2*" %%a in ('findstr /C:"//| mill-version:" %MILL_BUILD_SCRIPT%') do ( + set "MILL_VERSION=%%c" + ) + ) else ( + rem no-op + ) + ) + ) +) + +if [!MILL_VERSION!]==[] set MILL_VERSION=%DEFAULT_MILL_VERSION% + +if [!MILL_DOWNLOAD_PATH!]==[] set MILL_DOWNLOAD_PATH=%USERPROFILE%\.mill\download + +rem without bat file extension, cmd doesn't seem to be able to run it + +set "MILL_NATIVE_SUFFIX=-native" +set "MILL_JVM_SUFFIX=-jvm" +set "FULL_MILL_VERSION=%MILL_VERSION%" +set "MILL_EXT=.bat" +set "ARTIFACT_SUFFIX=" +REM Check if MILL_VERSION contains MILL_NATIVE_SUFFIX +echo !MILL_VERSION! | findstr /C:"%MILL_NATIVE_SUFFIX%" >nul +if !errorlevel! equ 0 ( + set "MILL_VERSION=%MILL_VERSION:-native=%" + REM -native images compiled with graal do not support windows-arm + REM https://github.com/oracle/graal/issues/9215 + IF /I NOT "%PROCESSOR_ARCHITECTURE%"=="ARM64" ( + set "ARTIFACT_SUFFIX=-native-windows-amd64" + set "MILL_EXT=.exe" + ) else ( + rem no-op + ) +) else ( + echo !MILL_VERSION! | findstr /C:"%MILL_JVM_SUFFIX%" >nul + if !errorlevel! equ 0 ( + set "MILL_VERSION=%MILL_VERSION:-jvm=%" + ) else ( + set "SKIP_VERSION=false" + set "MILL_PREFIX=%MILL_VERSION:~0,4%" + if "!MILL_PREFIX!"=="0.1." set "SKIP_VERSION=true" + if "!MILL_PREFIX!"=="0.2." set "SKIP_VERSION=true" + if "!MILL_PREFIX!"=="0.3." set "SKIP_VERSION=true" + if "!MILL_PREFIX!"=="0.4." set "SKIP_VERSION=true" + if "!MILL_PREFIX!"=="0.5." set "SKIP_VERSION=true" + if "!MILL_PREFIX!"=="0.6." set "SKIP_VERSION=true" + if "!MILL_PREFIX!"=="0.7." set "SKIP_VERSION=true" + if "!MILL_PREFIX!"=="0.8." set "SKIP_VERSION=true" + if "!MILL_PREFIX!"=="0.9." set "SKIP_VERSION=true" + set "MILL_PREFIX=%MILL_VERSION:~0,5%" + if "!MILL_PREFIX!"=="0.10." set "SKIP_VERSION=true" + if "!MILL_PREFIX!"=="0.11." set "SKIP_VERSION=true" + if "!MILL_PREFIX!"=="0.12." set "SKIP_VERSION=true" + + if "!SKIP_VERSION!"=="false" ( + IF /I NOT "%PROCESSOR_ARCHITECTURE%"=="ARM64" ( + set "ARTIFACT_SUFFIX=-native-windows-amd64" + set "MILL_EXT=.exe" + ) + ) else ( + rem no-op + ) + ) +) + +set MILL=%MILL_DOWNLOAD_PATH%\!FULL_MILL_VERSION!!MILL_EXT! + +set MILL_RESOLVE_DOWNLOAD= + +if not exist "%MILL%" ( + set MILL_RESOLVE_DOWNLOAD=true +) else ( + if defined MILL_TEST_DRY_RUN_LAUNCHER_SCRIPT ( + set MILL_RESOLVE_DOWNLOAD=true + ) else ( + rem no-op + ) +) + + +if [!MILL_RESOLVE_DOWNLOAD!]==[true] ( + set MILL_VERSION_PREFIX=%MILL_VERSION:~0,4% + set MILL_SHORT_VERSION_PREFIX=%MILL_VERSION:~0,2% + rem Since 0.5.0 + set MILL_DOWNLOAD_SUFFIX=-assembly + rem Since 0.11.0 + set MILL_DOWNLOAD_FROM_MAVEN=1 + if [!MILL_VERSION_PREFIX!]==[0.0.] ( + set MILL_DOWNLOAD_SUFFIX= + set MILL_DOWNLOAD_FROM_MAVEN=0 + ) + if [!MILL_VERSION_PREFIX!]==[0.1.] ( + set MILL_DOWNLOAD_SUFFIX= + set MILL_DOWNLOAD_FROM_MAVEN=0 + ) + if [!MILL_VERSION_PREFIX!]==[0.2.] ( + set MILL_DOWNLOAD_SUFFIX= + set MILL_DOWNLOAD_FROM_MAVEN=0 + ) + if [!MILL_VERSION_PREFIX!]==[0.3.] ( + set MILL_DOWNLOAD_SUFFIX= + set MILL_DOWNLOAD_FROM_MAVEN=0 + ) + if [!MILL_VERSION_PREFIX!]==[0.4.] ( + set MILL_DOWNLOAD_SUFFIX= + set MILL_DOWNLOAD_FROM_MAVEN=0 + ) + if [!MILL_VERSION_PREFIX!]==[0.5.] set MILL_DOWNLOAD_FROM_MAVEN=0 + if [!MILL_VERSION_PREFIX!]==[0.6.] set MILL_DOWNLOAD_FROM_MAVEN=0 + if [!MILL_VERSION_PREFIX!]==[0.7.] set MILL_DOWNLOAD_FROM_MAVEN=0 + if [!MILL_VERSION_PREFIX!]==[0.8.] set MILL_DOWNLOAD_FROM_MAVEN=0 + if [!MILL_VERSION_PREFIX!]==[0.9.] set MILL_DOWNLOAD_FROM_MAVEN=0 + + set MILL_VERSION_PREFIX=%MILL_VERSION:~0,5% + if [!MILL_VERSION_PREFIX!]==[0.10.] set MILL_DOWNLOAD_FROM_MAVEN=0 + + set MILL_VERSION_PREFIX=%MILL_VERSION:~0,8% + if [!MILL_VERSION_PREFIX!]==[0.11.0-M] set MILL_DOWNLOAD_FROM_MAVEN=0 + + set MILL_VERSION_PREFIX=%MILL_VERSION:~0,5% + set DOWNLOAD_EXT=exe + if [!MILL_SHORT_VERSION_PREFIX!]==[0.] set DOWNLOAD_EXT=jar + if [!MILL_VERSION_PREFIX!]==[0.12.] set DOWNLOAD_EXT=exe + if [!MILL_VERSION!]==[0.12.0] set DOWNLOAD_EXT=jar + if [!MILL_VERSION!]==[0.12.1] set DOWNLOAD_EXT=jar + if [!MILL_VERSION!]==[0.12.2] set DOWNLOAD_EXT=jar + if [!MILL_VERSION!]==[0.12.3] set DOWNLOAD_EXT=jar + if [!MILL_VERSION!]==[0.12.4] set DOWNLOAD_EXT=jar + if [!MILL_VERSION!]==[0.12.5] set DOWNLOAD_EXT=jar + if [!MILL_VERSION!]==[0.12.6] set DOWNLOAD_EXT=jar + if [!MILL_VERSION!]==[0.12.7] set DOWNLOAD_EXT=jar + if [!MILL_VERSION!]==[0.12.8] set DOWNLOAD_EXT=jar + if [!MILL_VERSION!]==[0.12.9] set DOWNLOAD_EXT=jar + if [!MILL_VERSION!]==[0.12.10] set DOWNLOAD_EXT=jar + if [!MILL_VERSION!]==[0.12.11] set DOWNLOAD_EXT=jar + + set MILL_VERSION_PREFIX= + set MILL_SHORT_VERSION_PREFIX= + + for /F "delims=- tokens=1" %%A in ("!MILL_VERSION!") do set MILL_VERSION_BASE=%%A + set MILL_VERSION_MILESTONE= + for /F "delims=- tokens=2" %%A in ("!MILL_VERSION!") do set MILL_VERSION_MILESTONE=%%A + set MILL_VERSION_MILESTONE_START=!MILL_VERSION_MILESTONE:~0,1! + if [!MILL_VERSION_MILESTONE_START!]==[M] ( + set MILL_VERSION_TAG=!MILL_VERSION_BASE!-!MILL_VERSION_MILESTONE! + ) else ( + set MILL_VERSION_TAG=!MILL_VERSION_BASE! + ) + if [!MILL_DOWNLOAD_FROM_MAVEN!]==[1] ( + set MILL_DOWNLOAD_URL=https://repo1.maven.org/maven2/com/lihaoyi/mill-dist!ARTIFACT_SUFFIX!/!MILL_VERSION!/mill-dist!ARTIFACT_SUFFIX!-!MILL_VERSION!.!DOWNLOAD_EXT! + ) else ( + set MILL_DOWNLOAD_URL=!MILL_GITHUB_RELEASE_CDN!%MILL_REPO_URL%/releases/download/!MILL_VERSION_TAG!/!MILL_VERSION!!MILL_DOWNLOAD_SUFFIX! + ) + + if defined MILL_TEST_DRY_RUN_LAUNCHER_SCRIPT ( + echo !MILL_DOWNLOAD_URL! + echo !MILL! + exit /b 0 + ) + + rem there seems to be no way to generate a unique temporary file path (on native Windows) + set MILL_DOWNLOAD_FILE=%MILL%.tmp + + echo Downloading mill !MILL_VERSION! from !MILL_DOWNLOAD_URL! ... 1>&2 + + if not exist "%MILL_DOWNLOAD_PATH%" mkdir "%MILL_DOWNLOAD_PATH%" + rem curl is bundled with recent Windows 10 + rem but I don't think we can expect all the users to have it in 2019 + where /Q curl + if !ERRORLEVEL! EQU 0 ( + curl -f -L "!MILL_DOWNLOAD_URL!" -o "!MILL_DOWNLOAD_FILE!" + ) else ( + rem bitsadmin seems to be available on Windows 7 + rem without /dynamic, github returns 403 + rem bitsadmin is sometimes needlessly slow but it looks better with /priority foreground + bitsadmin /transfer millDownloadJob /dynamic /priority foreground "!MILL_DOWNLOAD_URL!" "!MILL_DOWNLOAD_FILE!" + ) + if not exist "!MILL_DOWNLOAD_FILE!" ( + echo Could not download mill !MILL_VERSION! 1>&2 + exit /b 1 + ) + + move /y "!MILL_DOWNLOAD_FILE!" "%MILL%" + + set MILL_DOWNLOAD_FILE= + set MILL_DOWNLOAD_SUFFIX= +) + +set MILL_DOWNLOAD_PATH= +set MILL_VERSION= +set MILL_REPO_URL= + +rem Need to preserve the first position of those listed options +set MILL_FIRST_ARG= +if [%~1%]==[--bsp] ( + set MILL_FIRST_ARG=%1% +) else ( + if [%~1%]==[-i] ( + set MILL_FIRST_ARG=%1% + ) else ( + if [%~1%]==[--interactive] ( + set MILL_FIRST_ARG=%1% + ) else ( + if [%~1%]==[--no-server] ( + set MILL_FIRST_ARG=%1% + ) else ( + if [%~1%]==[--repl] ( + set MILL_FIRST_ARG=%1% + ) else ( + if [%~1%]==[--help] ( + set MILL_FIRST_ARG=%1% + ) + ) + ) + ) + ) +) + +set "MILL_PARAMS=%*%" + +if not [!MILL_FIRST_ARG!]==[] ( + for /f "tokens=1*" %%a in ("%*") do ( + set "MILL_PARAMS=%%b" + ) +) + +rem -D mill.main.cli is for compatibility with Mill 0.10.9 - 0.13.0-M2 +"%MILL%" %MILL_FIRST_ARG% -D "mill.main.cli=%MILL_MAIN_CLI%" %MILL_PARAMS% From b95f0f7df62956fbb9a9363bcc93025608ec7dfa Mon Sep 17 00:00:00 2001 From: rina Date: Mon, 7 Jul 2025 13:23:15 +1000 Subject: [PATCH 2/9] mill 1.0-rc3 --- offlineASL-scala/.mill-version | 1 - offlineASL-scala/build.mill | 21 +++++++++++++++++++++ offlineASL-scala/build.sc | 20 -------------------- 3 files changed, 21 insertions(+), 21 deletions(-) delete mode 100644 offlineASL-scala/.mill-version create mode 100644 offlineASL-scala/build.mill delete mode 100644 offlineASL-scala/build.sc diff --git a/offlineASL-scala/.mill-version b/offlineASL-scala/.mill-version deleted file mode 100644 index d0834a7f..00000000 --- a/offlineASL-scala/.mill-version +++ /dev/null @@ -1 +0,0 @@ -0.12.14 diff --git a/offlineASL-scala/build.mill b/offlineASL-scala/build.mill new file mode 100644 index 00000000..c0531dd1 --- /dev/null +++ b/offlineASL-scala/build.mill @@ -0,0 +1,21 @@ +//| mill-version: 1.0.0-RC3-31-eb2d11-jvm + +import mill._, scalalib._ + +object lifter extends ScalaModule { + override def scalaVersion = "3.3.6" +} + +object main extends ScalaModule { + override def scalaVersion = "3.3.6" + + override def moduleDeps = Seq(lifter) + + override def mvnDeps = Seq( + mvn"com.lihaoyi::mainargs:0.6.2", + mvn"com.lihaoyi::sourcecode:0.3.0" + ) + + override def mainClass = Some("main.Main") +} + diff --git a/offlineASL-scala/build.sc b/offlineASL-scala/build.sc deleted file mode 100644 index 4592a687..00000000 --- a/offlineASL-scala/build.sc +++ /dev/null @@ -1,20 +0,0 @@ -import mill._, scalalib._ - -object lifter extends ScalaModule { - def scalaVersion = "3.3.6" -} - -object main extends ScalaModule { - def scalaVersion = "3.3.6" - - def moduleDeps = Seq(lifter) - - def ivyDeps = Agg( - ivy"com.lihaoyi::mainargs:0.6.2", - ivy"com.lihaoyi::sourcecode:0.3.0" - ) - - def mainClass = Some("main.Main") - -} - From 0a2d3e58a526a8709ce657e64da431ba6bd8f1b1 Mon Sep 17 00:00:00 2001 From: rina Date: Mon, 7 Jul 2025 13:39:24 +1000 Subject: [PATCH 3/9] sonatype --- offlineASL-scala/build.mill | 5 + offlineASL-scala/millfiles/package.mill | 403 ++++++++++++++++++++++++ 2 files changed, 408 insertions(+) create mode 100644 offlineASL-scala/millfiles/package.mill diff --git a/offlineASL-scala/build.mill b/offlineASL-scala/build.mill index c0531dd1..a5135c4a 100644 --- a/offlineASL-scala/build.mill +++ b/offlineASL-scala/build.mill @@ -1,7 +1,12 @@ //| mill-version: 1.0.0-RC3-31-eb2d11-jvm +//| mvnDeps: ["com.lumidion::sonatype-central-client-requests:0.6.0"] +// vim: ts=2 sts=2 et sw=2 syntax=scala +package build import mill._, scalalib._ +import build.millfiles.SonatypeCentralPublishModule + object lifter extends ScalaModule { override def scalaVersion = "3.3.6" } diff --git a/offlineASL-scala/millfiles/package.mill b/offlineASL-scala/millfiles/package.mill new file mode 100644 index 00000000..9ee7bf10 --- /dev/null +++ b/offlineASL-scala/millfiles/package.mill @@ -0,0 +1,403 @@ +package build.millfiles + +import com.lumidion.sonatype.central.client.core.{PublishingType, SonatypeCredentials} +import mill._ +import scalalib._ +import mill.api.{ExternalModule, Task} +import mill.util.Tasks +import mill.api.TaskModule +import mill.api.{Result, experimental} +import SonatypeCentralPublishModule.{ + defaultAwaitTimeout, + defaultConnectTimeout, + defaultCredentials, + defaultReadTimeout, + getPublishingTypeFromReleaseFlag, + getSonatypeCredentials +} +import mill.scalalib.publish.Artifact +import mill.scalalib.publish.SonatypeHelpers.{ + PASSWORD_ENV_VARIABLE_NAME, + USERNAME_ENV_VARIABLE_NAME +} +import mill.api.BuildCtx + +extension (x: PublishModule.PublishData) + def withConcretePath: (Seq[(os.Path, String)], Artifact) = + (x.payload.map { case (p, f) => (p.path, f) }, x.meta) + +@experimental +trait SonatypeCentralPublishModule extends PublishModule { + def sonatypeCentralGpgArgs: T[String] = Task { + PublishModule.defaultGpgArgsForPassphrase(Task.env.get("MILL_PGP_PASSPHRASE")).mkString(",") + } + + def sonatypeCentralConnectTimeout: T[Int] = Task { defaultConnectTimeout } + + def sonatypeCentralReadTimeout: T[Int] = Task { defaultReadTimeout } + + def sonatypeCentralAwaitTimeout: T[Int] = Task { defaultAwaitTimeout } + + def sonatypeCentralShouldRelease: T[Boolean] = Task { true } + + def publishSonatypeCentral( + username: String = defaultCredentials, + password: String = defaultCredentials + ): Task.Command[Unit] = + Task.Command { + val publishData = publishArtifacts() + val fileMapping = publishData.withConcretePath._1 + val artifact = publishData.meta + val finalCredentials = getSonatypeCredentials(username, password)() + PublishModule.pgpImportSecretIfProvided(Task.env) + val publisher = new SonatypeCentralPublisher( + credentials = finalCredentials, + gpgArgs = sonatypeCentralGpgArgs().split(",").toIndexedSeq, + connectTimeout = sonatypeCentralConnectTimeout(), + readTimeout = sonatypeCentralReadTimeout(), + log = Task.log, + workspace = BuildCtx.workspaceRoot, + env = Task.env, + awaitTimeout = sonatypeCentralAwaitTimeout() + ) + publisher.publish( + fileMapping, + artifact, + getPublishingTypeFromReleaseFlag(sonatypeCentralShouldRelease()) + ) + } +} + +object SonatypeCentralPublishModule extends ExternalModule with TaskModule { + + def self = this + val defaultCredentials: String = "" + val defaultReadTimeout: Int = 60000 + val defaultConnectTimeout: Int = 5000 + val defaultAwaitTimeout: Int = 120 * 1000 + val defaultShouldRelease: Boolean = true + + // Set the default command to "publishAll" + def defaultTask(): String = "publishAll" + + def publishAll( + publishArtifacts: mill.util.Tasks[PublishModule.PublishData] = + Tasks.resolveMainDefault("__:PublishModule.publishArtifacts"), + username: String = defaultCredentials, + password: String = defaultCredentials, + shouldRelease: Boolean = defaultShouldRelease, + gpgArgs: String = "", + readTimeout: Int = defaultReadTimeout, + connectTimeout: Int = defaultConnectTimeout, + awaitTimeout: Int = defaultAwaitTimeout, + bundleName: String = "" + ): Command[Unit] = Task.Command { + + val artifacts: Seq[(Seq[(os.Path, String)], Artifact)] = + Task.sequence(publishArtifacts.value)().map { + case data @ PublishModule.PublishData(_, _) => data.withConcretePath + } + + val finalBundleName = if (bundleName.isEmpty) None else Some(bundleName) + val finalCredentials = getSonatypeCredentials(username, password)() + PublishModule.pgpImportSecretIfProvided(Task.env) + val publisher = new SonatypeCentralPublisher( + credentials = finalCredentials, + gpgArgs = gpgArgs match { + case "" => PublishModule.defaultGpgArgsForPassphrase(Task.env.get("MILL_PGP_PASSPHRASE")) + case gpgArgs => gpgArgs.split(",").toIndexedSeq + }, + connectTimeout = connectTimeout, + readTimeout = readTimeout, + log = Task.log, + workspace = BuildCtx.workspaceRoot, + env = Task.env, + awaitTimeout = awaitTimeout + ) + Task.ctx().log.info(s"artifacts ${pprint.apply(artifacts)}") + publisher.publishAll( + getPublishingTypeFromReleaseFlag(shouldRelease), + finalBundleName, + artifacts* + ) + } + + private def getPublishingTypeFromReleaseFlag(shouldRelease: Boolean): PublishingType = { + if (shouldRelease) { + PublishingType.AUTOMATIC + } else { + PublishingType.USER_MANAGED + } + } + + private def getSonatypeCredential( + credentialParameterValue: String, + credentialName: String, + envVariableName: String + ): Task[String] = Task.Anon { + if (credentialParameterValue.nonEmpty) { + Result.Success(credentialParameterValue) + } else { + (for { + credential <- Task.env.get(envVariableName) + } yield { + Result.Success(credential) + }).getOrElse( + Result.Failure( + s"No $credentialName set. Consider using the $envVariableName environment variable or passing `$credentialName` argument" + ) + ) + } + } + + private def getSonatypeCredentials( + usernameParameterValue: String, + passwordParameterValue: String + ): Task[SonatypeCredentials] = Task.Anon { + val username = + getSonatypeCredential(usernameParameterValue, "username", USERNAME_ENV_VARIABLE_NAME)() + val password = + getSonatypeCredential(passwordParameterValue, "password", PASSWORD_ENV_VARIABLE_NAME)() + Result.Success(SonatypeCredentials(username, password)) + } + + lazy val millDiscover: mill.api.Discover = mill.api.Discover[this.type] +} + + +import com.lumidion.sonatype.central.client.core.{ + DeploymentName, + PublishingType, + SonatypeCredentials +} +import com.lumidion.sonatype.central.client.requests.SyncSonatypeClient +import mill.api.{Logger, Result} +import mill.scalalib.publish.Artifact +import SonatypeHelpers.getArtifactMappings + +import java.nio.file.Files +import java.util.jar.JarOutputStream +import java.util.zip.ZipEntry + +class SonatypeCentralPublisher( + credentials: SonatypeCredentials, + gpgArgs: Seq[String], + readTimeout: Int, + connectTimeout: Int, + log: Logger, + workspace: os.Path, + env: Map[String, String], + awaitTimeout: Int +) { + private val sonatypeCentralClient = + new SyncSonatypeClient(credentials, readTimeout = readTimeout, connectTimeout = connectTimeout) + + def publish( + fileMapping: Seq[(os.Path, String)], + artifact: Artifact, + publishingType: PublishingType + ): Unit = { + publishAll(publishingType, None, fileMapping -> artifact) + } + + def publishAll( + publishingType: PublishingType, + singleBundleName: Option[String], + artifacts: (Seq[(os.Path, String)], Artifact)* + ): Unit = { + val mappings = getArtifactMappings(isSigned = true, gpgArgs, workspace, env, artifacts) + log.info(s"mappings ${pprint.apply(mappings.map { case (a, kvs) => (a, kvs.map(_._1)) })}") + val (snapshots, releases) = mappings.partition(_._1.isSnapshot) + if (snapshots.nonEmpty) { + val snapshotNames = snapshots.map(_._1) + .map { case Artifact(group, id, version) => s"$group:$id:$version" } + throw new Result.Exception( + s"""Publishing snapshots to Sonatype Central Portal is currently not supported by Mill. + |This is tracked under https://github.com/com-lihaoyi/mill/issues/4421 + |The following snapshots will not be published: + | ${snapshotNames.mkString("\n ")}""".stripMargin + ) + } + if (releases.isEmpty) { + log.error("No releases to publish to Sonatype Central.") + val errorMessage = + "No releases to publish to Sonatype Central." + + (if (snapshots.nonEmpty) + "It seems there were only snapshots to publish, which is not supported by Mill, currently." + else "Please check your build configuration.") + throw new Result.Exception(errorMessage) + } + + val releaseGroups = releases.groupBy(_._1.group) + val wd = os.pwd / "out/publish-central" + os.makeDir.all(wd) + + singleBundleName.fold { + for ((_, groupReleases) <- releaseGroups) { + groupReleases.foreach { case (artifact, data) => + val fileNameWithoutExtension = s"${artifact.group}-${artifact.id}-${artifact.version}" + val zipFile = streamToFile(fileNameWithoutExtension, wd) { outputStream => + log.info(s"bundle $fileNameWithoutExtension with ${pprint.apply(data.map(_._1))}") + zipFilesToJar(data, outputStream) + } + + val deploymentName = DeploymentName.fromArtifact( + artifact.group, + artifact.id, + artifact.version + ) + publishFile(zipFile, deploymentName, publishingType) + } + } + + } { singleBundleName => + val zipFile = streamToFile(singleBundleName, wd) { outputStream => + for ((_, groupReleases) <- releaseGroups) { + groupReleases.foreach { case (_, data) => + zipFilesToJar(data, outputStream) + } + } + } + + val deploymentName = DeploymentName(singleBundleName) + + publishFile(zipFile, deploymentName, publishingType) + } + } + + private def publishFile( + zipFile: java.io.File, + deploymentName: DeploymentName, + publishingType: PublishingType + ): Unit = { + try { + mill.util.Retry( + count = 5, + backoffMillis = 1000, + filter = (_, ex) => ex.getMessage.contains("Read end dead") + ) { + sonatypeCentralClient.uploadBundleFromFile( + zipFile, + deploymentName, + Some(publishingType), + timeout = awaitTimeout + ) + } + } catch { + case ex: Throwable => { + throw new RuntimeException( + s"Failed to publish ${deploymentName.unapply} to Sonatype Central", + ex + ) + } + } + + log.info(s"Successfully published ${deploymentName.unapply} to Sonatype Central") + } + + private def streamToFile( + fileNameWithoutExtension: String, + wd: os.Path + )(func: JarOutputStream => Unit): java.io.File = { + val zipFile = + (wd / s"$fileNameWithoutExtension.zip") + val fileOutputStream = Files.newOutputStream(zipFile.toNIO) + val jarOutputStream = new JarOutputStream(fileOutputStream) + try { + func(jarOutputStream) + } finally { + jarOutputStream.close() + } + zipFile.toIO + } + + private def zipFilesToJar( + files: Seq[(String, Array[Byte])], + jarOutputStream: JarOutputStream + ): Unit = { + files.foreach { case (filename, fileAsBytes) => + val zipEntry = new ZipEntry(filename) + jarOutputStream.putNextEntry(zipEntry) + jarOutputStream.write(fileAsBytes) + jarOutputStream.closeEntry() + } + } +} + + +import java.math.BigInteger +import java.security.MessageDigest + +object SonatypeHelpers { + // http://central.sonatype.org/pages/working-with-pgp-signatures.html#signing-a-file + + val USERNAME_ENV_VARIABLE_NAME = "MILL_SONATYPE_USERNAME" + val PASSWORD_ENV_VARIABLE_NAME = "MILL_SONATYPE_PASSWORD" + + def getArtifactMappings( + isSigned: Boolean, + gpgArgs: Seq[String], + workspace: os.Path, + env: Map[String, String], + artifacts: Seq[(Seq[(os.Path, String)], Artifact)] + ): Seq[(Artifact, Seq[(String, Array[Byte])])] = { + for ((fileMapping0, artifact) <- artifacts) yield { + val publishPath = Seq( + artifact.group.replace(".", "/"), + artifact.id, + artifact.version + ).mkString("/") + val fileMapping = fileMapping0.map { case (file, name) => (file, publishPath + "/" + name) } + + val signedArtifacts = + if (isSigned) fileMapping.map { + case (file, name) => + gpgSigned(file = file, args = gpgArgs, workspace = workspace, env = env) -> s"$name.asc" + } + else Seq() + + artifact -> (fileMapping ++ signedArtifacts).flatMap { + case (file, name) => + val content = os.read.bytes(file) + + Seq( + name -> content, + (name + ".md5") -> md5hex(content), + (name + ".sha1") -> sha1hex(content) + ) + } + } + } + private def gpgSigned( + file: os.Path, + args: Seq[String], + workspace: os.Path, + env: Map[String, String] + ): os.Path = { + val fileName = file.toString + val command = "gpg" +: args :+ fileName + + os.call( + command, + env, + workspace, + stdin = os.Inherit, + stdout = os.Inherit, + stderr = os.Inherit + ) + os.Path(fileName + ".asc") + } + + private def md5hex(bytes: Array[Byte]): Array[Byte] = + hexArray(md5.digest(bytes)).getBytes + + private def sha1hex(bytes: Array[Byte]): Array[Byte] = + hexArray(sha1.digest(bytes)).getBytes + + private def md5 = MessageDigest.getInstance("md5") + + private def sha1 = MessageDigest.getInstance("sha1") + + private def hexArray(arr: Array[Byte]) = + String.format("%0" + (arr.length << 1) + "x", new BigInteger(1, arr)) +} From 75594e7b0e1cf2d1792ac3ccd599c0178bcc142e Mon Sep 17 00:00:00 2001 From: rina Date: Mon, 7 Jul 2025 14:48:27 +1000 Subject: [PATCH 4/9] artifactory works --- offlineASL-scala/build.mill | 23 ++++++++++++++++++++--- offlineASL-scala/millfiles/package.mill | 16 ++++++++++------ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/offlineASL-scala/build.mill b/offlineASL-scala/build.mill index a5135c4a..32f99bd4 100644 --- a/offlineASL-scala/build.mill +++ b/offlineASL-scala/build.mill @@ -1,14 +1,31 @@ //| mill-version: 1.0.0-RC3-31-eb2d11-jvm -//| mvnDeps: ["com.lumidion::sonatype-central-client-requests:0.6.0"] +//| mvnDeps: ["com.lumidion::sonatype-central-client-requests:0.6.0", "com.lihaoyi::mill-contrib-codeartifact:$MILL_VERSION", "com.lihaoyi::mill-contrib-artifactory:$MILL_VERSION"] // vim: ts=2 sts=2 et sw=2 syntax=scala package build -import mill._, scalalib._ +import mill._, scalalib._, publish._ import build.millfiles.SonatypeCentralPublishModule +import mill.contrib.artifactory.ArtifactoryPublishModule -object lifter extends ScalaModule { +object lifter extends ScalaModule with ArtifactoryPublishModule { override def scalaVersion = "3.3.6" + + override def artifactoryUri = "https://maven.pkg.github.com/UQ-PAC/aslp" + override def artifactorySnapshotUri: String = artifactoryUri + + override def publishVersion = "0.0.1" + + override def docSources = Seq[PathRef]() + + override def pomSettings = PomSettings( + description = "ASLp Offline Scala Lifter", + organization = "io.github.uq-pac", + url = "https://github.com/UQ-PAC/aslp", + licenses = Seq(License.MIT), + versionControl = VersionControl.github("UQ-PAC", "aslp"), + developers = Seq(Developer("katrinafyi", "rina", "https://github.com/katrinafyi")) + ) } object main extends ScalaModule { diff --git a/offlineASL-scala/millfiles/package.mill b/offlineASL-scala/millfiles/package.mill index 9ee7bf10..45af3013 100644 --- a/offlineASL-scala/millfiles/package.mill +++ b/offlineASL-scala/millfiles/package.mill @@ -1,4 +1,5 @@ package build.millfiles +// vim: ts=2 sts=2 et sw=2 syntax=scala import com.lumidion.sonatype.central.client.core.{PublishingType, SonatypeCredentials} import mill._ @@ -41,8 +42,8 @@ trait SonatypeCentralPublishModule extends PublishModule { def sonatypeCentralShouldRelease: T[Boolean] = Task { true } def publishSonatypeCentral( - username: String = defaultCredentials, - password: String = defaultCredentials + username: String = "", + password: String = "" ): Task.Command[Unit] = Task.Command { val publishData = publishArtifacts() @@ -68,7 +69,7 @@ trait SonatypeCentralPublishModule extends PublishModule { } } -object SonatypeCentralPublishModule extends ExternalModule with TaskModule { +object SonatypeCentralPublishModule extends TaskModule { def self = this val defaultCredentials: String = "" @@ -83,8 +84,8 @@ object SonatypeCentralPublishModule extends ExternalModule with TaskModule { def publishAll( publishArtifacts: mill.util.Tasks[PublishModule.PublishData] = Tasks.resolveMainDefault("__:PublishModule.publishArtifacts"), - username: String = defaultCredentials, - password: String = defaultCredentials, + username: String = "", + password: String = "", shouldRelease: Boolean = defaultShouldRelease, gpgArgs: String = "", readTimeout: Int = defaultReadTimeout, @@ -190,7 +191,10 @@ class SonatypeCentralPublisher( awaitTimeout: Int ) { private val sonatypeCentralClient = - new SyncSonatypeClient(credentials, readTimeout = readTimeout, connectTimeout = connectTimeout) + new SyncSonatypeClient( + credentials, readTimeout = readTimeout, connectTimeout = connectTimeout, + overrideEndpoint = Some("https://maven.pkg.github.com/UQ-PAC/aslp") + ) def publish( fileMapping: Seq[(os.Path, String)], From 7da356a677945a9a1da003de61941f87fe6bf2fc Mon Sep 17 00:00:00 2001 From: rina Date: Mon, 7 Jul 2025 14:54:24 +1000 Subject: [PATCH 5/9] clean --- offlineASL-scala/build.mill | 8 +- offlineASL-scala/millfiles/package.mill | 407 ------------------------ offlineASL-scala/readme.md | 19 ++ 3 files changed, 23 insertions(+), 411 deletions(-) delete mode 100644 offlineASL-scala/millfiles/package.mill diff --git a/offlineASL-scala/build.mill b/offlineASL-scala/build.mill index 32f99bd4..1cd6a096 100644 --- a/offlineASL-scala/build.mill +++ b/offlineASL-scala/build.mill @@ -1,7 +1,7 @@ //| mill-version: 1.0.0-RC3-31-eb2d11-jvm -//| mvnDeps: ["com.lumidion::sonatype-central-client-requests:0.6.0", "com.lihaoyi::mill-contrib-codeartifact:$MILL_VERSION", "com.lihaoyi::mill-contrib-artifactory:$MILL_VERSION"] +//| mvnDeps: ["com.lihaoyi::mill-contrib-artifactory:$MILL_VERSION"] -// vim: ts=2 sts=2 et sw=2 syntax=scala +// vim: ts=2 sts=2 et sw=2 ft=scala package build import mill._, scalalib._, publish._ @@ -14,9 +14,9 @@ object lifter extends ScalaModule with ArtifactoryPublishModule { override def artifactoryUri = "https://maven.pkg.github.com/UQ-PAC/aslp" override def artifactorySnapshotUri: String = artifactoryUri - override def publishVersion = "0.0.1" + override def publishVersion = "0.1.0" - override def docSources = Seq[PathRef]() + // override def docSources = Seq[PathRef]() override def pomSettings = PomSettings( description = "ASLp Offline Scala Lifter", diff --git a/offlineASL-scala/millfiles/package.mill b/offlineASL-scala/millfiles/package.mill deleted file mode 100644 index 45af3013..00000000 --- a/offlineASL-scala/millfiles/package.mill +++ /dev/null @@ -1,407 +0,0 @@ -package build.millfiles -// vim: ts=2 sts=2 et sw=2 syntax=scala - -import com.lumidion.sonatype.central.client.core.{PublishingType, SonatypeCredentials} -import mill._ -import scalalib._ -import mill.api.{ExternalModule, Task} -import mill.util.Tasks -import mill.api.TaskModule -import mill.api.{Result, experimental} -import SonatypeCentralPublishModule.{ - defaultAwaitTimeout, - defaultConnectTimeout, - defaultCredentials, - defaultReadTimeout, - getPublishingTypeFromReleaseFlag, - getSonatypeCredentials -} -import mill.scalalib.publish.Artifact -import mill.scalalib.publish.SonatypeHelpers.{ - PASSWORD_ENV_VARIABLE_NAME, - USERNAME_ENV_VARIABLE_NAME -} -import mill.api.BuildCtx - -extension (x: PublishModule.PublishData) - def withConcretePath: (Seq[(os.Path, String)], Artifact) = - (x.payload.map { case (p, f) => (p.path, f) }, x.meta) - -@experimental -trait SonatypeCentralPublishModule extends PublishModule { - def sonatypeCentralGpgArgs: T[String] = Task { - PublishModule.defaultGpgArgsForPassphrase(Task.env.get("MILL_PGP_PASSPHRASE")).mkString(",") - } - - def sonatypeCentralConnectTimeout: T[Int] = Task { defaultConnectTimeout } - - def sonatypeCentralReadTimeout: T[Int] = Task { defaultReadTimeout } - - def sonatypeCentralAwaitTimeout: T[Int] = Task { defaultAwaitTimeout } - - def sonatypeCentralShouldRelease: T[Boolean] = Task { true } - - def publishSonatypeCentral( - username: String = "", - password: String = "" - ): Task.Command[Unit] = - Task.Command { - val publishData = publishArtifacts() - val fileMapping = publishData.withConcretePath._1 - val artifact = publishData.meta - val finalCredentials = getSonatypeCredentials(username, password)() - PublishModule.pgpImportSecretIfProvided(Task.env) - val publisher = new SonatypeCentralPublisher( - credentials = finalCredentials, - gpgArgs = sonatypeCentralGpgArgs().split(",").toIndexedSeq, - connectTimeout = sonatypeCentralConnectTimeout(), - readTimeout = sonatypeCentralReadTimeout(), - log = Task.log, - workspace = BuildCtx.workspaceRoot, - env = Task.env, - awaitTimeout = sonatypeCentralAwaitTimeout() - ) - publisher.publish( - fileMapping, - artifact, - getPublishingTypeFromReleaseFlag(sonatypeCentralShouldRelease()) - ) - } -} - -object SonatypeCentralPublishModule extends TaskModule { - - def self = this - val defaultCredentials: String = "" - val defaultReadTimeout: Int = 60000 - val defaultConnectTimeout: Int = 5000 - val defaultAwaitTimeout: Int = 120 * 1000 - val defaultShouldRelease: Boolean = true - - // Set the default command to "publishAll" - def defaultTask(): String = "publishAll" - - def publishAll( - publishArtifacts: mill.util.Tasks[PublishModule.PublishData] = - Tasks.resolveMainDefault("__:PublishModule.publishArtifacts"), - username: String = "", - password: String = "", - shouldRelease: Boolean = defaultShouldRelease, - gpgArgs: String = "", - readTimeout: Int = defaultReadTimeout, - connectTimeout: Int = defaultConnectTimeout, - awaitTimeout: Int = defaultAwaitTimeout, - bundleName: String = "" - ): Command[Unit] = Task.Command { - - val artifacts: Seq[(Seq[(os.Path, String)], Artifact)] = - Task.sequence(publishArtifacts.value)().map { - case data @ PublishModule.PublishData(_, _) => data.withConcretePath - } - - val finalBundleName = if (bundleName.isEmpty) None else Some(bundleName) - val finalCredentials = getSonatypeCredentials(username, password)() - PublishModule.pgpImportSecretIfProvided(Task.env) - val publisher = new SonatypeCentralPublisher( - credentials = finalCredentials, - gpgArgs = gpgArgs match { - case "" => PublishModule.defaultGpgArgsForPassphrase(Task.env.get("MILL_PGP_PASSPHRASE")) - case gpgArgs => gpgArgs.split(",").toIndexedSeq - }, - connectTimeout = connectTimeout, - readTimeout = readTimeout, - log = Task.log, - workspace = BuildCtx.workspaceRoot, - env = Task.env, - awaitTimeout = awaitTimeout - ) - Task.ctx().log.info(s"artifacts ${pprint.apply(artifacts)}") - publisher.publishAll( - getPublishingTypeFromReleaseFlag(shouldRelease), - finalBundleName, - artifacts* - ) - } - - private def getPublishingTypeFromReleaseFlag(shouldRelease: Boolean): PublishingType = { - if (shouldRelease) { - PublishingType.AUTOMATIC - } else { - PublishingType.USER_MANAGED - } - } - - private def getSonatypeCredential( - credentialParameterValue: String, - credentialName: String, - envVariableName: String - ): Task[String] = Task.Anon { - if (credentialParameterValue.nonEmpty) { - Result.Success(credentialParameterValue) - } else { - (for { - credential <- Task.env.get(envVariableName) - } yield { - Result.Success(credential) - }).getOrElse( - Result.Failure( - s"No $credentialName set. Consider using the $envVariableName environment variable or passing `$credentialName` argument" - ) - ) - } - } - - private def getSonatypeCredentials( - usernameParameterValue: String, - passwordParameterValue: String - ): Task[SonatypeCredentials] = Task.Anon { - val username = - getSonatypeCredential(usernameParameterValue, "username", USERNAME_ENV_VARIABLE_NAME)() - val password = - getSonatypeCredential(passwordParameterValue, "password", PASSWORD_ENV_VARIABLE_NAME)() - Result.Success(SonatypeCredentials(username, password)) - } - - lazy val millDiscover: mill.api.Discover = mill.api.Discover[this.type] -} - - -import com.lumidion.sonatype.central.client.core.{ - DeploymentName, - PublishingType, - SonatypeCredentials -} -import com.lumidion.sonatype.central.client.requests.SyncSonatypeClient -import mill.api.{Logger, Result} -import mill.scalalib.publish.Artifact -import SonatypeHelpers.getArtifactMappings - -import java.nio.file.Files -import java.util.jar.JarOutputStream -import java.util.zip.ZipEntry - -class SonatypeCentralPublisher( - credentials: SonatypeCredentials, - gpgArgs: Seq[String], - readTimeout: Int, - connectTimeout: Int, - log: Logger, - workspace: os.Path, - env: Map[String, String], - awaitTimeout: Int -) { - private val sonatypeCentralClient = - new SyncSonatypeClient( - credentials, readTimeout = readTimeout, connectTimeout = connectTimeout, - overrideEndpoint = Some("https://maven.pkg.github.com/UQ-PAC/aslp") - ) - - def publish( - fileMapping: Seq[(os.Path, String)], - artifact: Artifact, - publishingType: PublishingType - ): Unit = { - publishAll(publishingType, None, fileMapping -> artifact) - } - - def publishAll( - publishingType: PublishingType, - singleBundleName: Option[String], - artifacts: (Seq[(os.Path, String)], Artifact)* - ): Unit = { - val mappings = getArtifactMappings(isSigned = true, gpgArgs, workspace, env, artifacts) - log.info(s"mappings ${pprint.apply(mappings.map { case (a, kvs) => (a, kvs.map(_._1)) })}") - val (snapshots, releases) = mappings.partition(_._1.isSnapshot) - if (snapshots.nonEmpty) { - val snapshotNames = snapshots.map(_._1) - .map { case Artifact(group, id, version) => s"$group:$id:$version" } - throw new Result.Exception( - s"""Publishing snapshots to Sonatype Central Portal is currently not supported by Mill. - |This is tracked under https://github.com/com-lihaoyi/mill/issues/4421 - |The following snapshots will not be published: - | ${snapshotNames.mkString("\n ")}""".stripMargin - ) - } - if (releases.isEmpty) { - log.error("No releases to publish to Sonatype Central.") - val errorMessage = - "No releases to publish to Sonatype Central." + - (if (snapshots.nonEmpty) - "It seems there were only snapshots to publish, which is not supported by Mill, currently." - else "Please check your build configuration.") - throw new Result.Exception(errorMessage) - } - - val releaseGroups = releases.groupBy(_._1.group) - val wd = os.pwd / "out/publish-central" - os.makeDir.all(wd) - - singleBundleName.fold { - for ((_, groupReleases) <- releaseGroups) { - groupReleases.foreach { case (artifact, data) => - val fileNameWithoutExtension = s"${artifact.group}-${artifact.id}-${artifact.version}" - val zipFile = streamToFile(fileNameWithoutExtension, wd) { outputStream => - log.info(s"bundle $fileNameWithoutExtension with ${pprint.apply(data.map(_._1))}") - zipFilesToJar(data, outputStream) - } - - val deploymentName = DeploymentName.fromArtifact( - artifact.group, - artifact.id, - artifact.version - ) - publishFile(zipFile, deploymentName, publishingType) - } - } - - } { singleBundleName => - val zipFile = streamToFile(singleBundleName, wd) { outputStream => - for ((_, groupReleases) <- releaseGroups) { - groupReleases.foreach { case (_, data) => - zipFilesToJar(data, outputStream) - } - } - } - - val deploymentName = DeploymentName(singleBundleName) - - publishFile(zipFile, deploymentName, publishingType) - } - } - - private def publishFile( - zipFile: java.io.File, - deploymentName: DeploymentName, - publishingType: PublishingType - ): Unit = { - try { - mill.util.Retry( - count = 5, - backoffMillis = 1000, - filter = (_, ex) => ex.getMessage.contains("Read end dead") - ) { - sonatypeCentralClient.uploadBundleFromFile( - zipFile, - deploymentName, - Some(publishingType), - timeout = awaitTimeout - ) - } - } catch { - case ex: Throwable => { - throw new RuntimeException( - s"Failed to publish ${deploymentName.unapply} to Sonatype Central", - ex - ) - } - } - - log.info(s"Successfully published ${deploymentName.unapply} to Sonatype Central") - } - - private def streamToFile( - fileNameWithoutExtension: String, - wd: os.Path - )(func: JarOutputStream => Unit): java.io.File = { - val zipFile = - (wd / s"$fileNameWithoutExtension.zip") - val fileOutputStream = Files.newOutputStream(zipFile.toNIO) - val jarOutputStream = new JarOutputStream(fileOutputStream) - try { - func(jarOutputStream) - } finally { - jarOutputStream.close() - } - zipFile.toIO - } - - private def zipFilesToJar( - files: Seq[(String, Array[Byte])], - jarOutputStream: JarOutputStream - ): Unit = { - files.foreach { case (filename, fileAsBytes) => - val zipEntry = new ZipEntry(filename) - jarOutputStream.putNextEntry(zipEntry) - jarOutputStream.write(fileAsBytes) - jarOutputStream.closeEntry() - } - } -} - - -import java.math.BigInteger -import java.security.MessageDigest - -object SonatypeHelpers { - // http://central.sonatype.org/pages/working-with-pgp-signatures.html#signing-a-file - - val USERNAME_ENV_VARIABLE_NAME = "MILL_SONATYPE_USERNAME" - val PASSWORD_ENV_VARIABLE_NAME = "MILL_SONATYPE_PASSWORD" - - def getArtifactMappings( - isSigned: Boolean, - gpgArgs: Seq[String], - workspace: os.Path, - env: Map[String, String], - artifacts: Seq[(Seq[(os.Path, String)], Artifact)] - ): Seq[(Artifact, Seq[(String, Array[Byte])])] = { - for ((fileMapping0, artifact) <- artifacts) yield { - val publishPath = Seq( - artifact.group.replace(".", "/"), - artifact.id, - artifact.version - ).mkString("/") - val fileMapping = fileMapping0.map { case (file, name) => (file, publishPath + "/" + name) } - - val signedArtifacts = - if (isSigned) fileMapping.map { - case (file, name) => - gpgSigned(file = file, args = gpgArgs, workspace = workspace, env = env) -> s"$name.asc" - } - else Seq() - - artifact -> (fileMapping ++ signedArtifacts).flatMap { - case (file, name) => - val content = os.read.bytes(file) - - Seq( - name -> content, - (name + ".md5") -> md5hex(content), - (name + ".sha1") -> sha1hex(content) - ) - } - } - } - private def gpgSigned( - file: os.Path, - args: Seq[String], - workspace: os.Path, - env: Map[String, String] - ): os.Path = { - val fileName = file.toString - val command = "gpg" +: args :+ fileName - - os.call( - command, - env, - workspace, - stdin = os.Inherit, - stdout = os.Inherit, - stderr = os.Inherit - ) - os.Path(fileName + ".asc") - } - - private def md5hex(bytes: Array[Byte]): Array[Byte] = - hexArray(md5.digest(bytes)).getBytes - - private def sha1hex(bytes: Array[Byte]): Array[Byte] = - hexArray(sha1.digest(bytes)).getBytes - - private def md5 = MessageDigest.getInstance("md5") - - private def sha1 = MessageDigest.getInstance("sha1") - - private def hexArray(arr: Array[Byte]) = - String.format("%0" + (arr.length << 1) + "x", new BigInteger(1, arr)) -} diff --git a/offlineASL-scala/readme.md b/offlineASL-scala/readme.md index 742c22b2..b7e9e23f 100644 --- a/offlineASL-scala/readme.md +++ b/offlineASL-scala/readme.md @@ -11,3 +11,22 @@ mill main.run --opcode 0x8b031041 This should compile successfully. However, the last command will fail since the default instruction-building interface simply throws "not implemented" on all methods. + +## Github Packages repository + +The compiled offline lifter is uploaded to +[Github Packages](https://github.com/orgs/UQ-PAC/packages?repo_name=aslp) which allows downstream +projects to download it like any other Scala dependency. + +To publish a new version, first increment `publishVersion` then run this command: +```bash +./mill lifter.publishArtifactory --credentials katrinafyi:ghp_AAA +``` +You will need to get a `write:packages` Github classic token. +See [the docs](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-apache-maven-registry). + +### Using as a dependency + +To download the package from Github packages, you will require a `read:packages` token. +One is included in the Basil build configuration (from @katrinafyi). + From 6a8543fbf474a9875ec0014f6fde14a9d1b1c390 Mon Sep 17 00:00:00 2001 From: rina Date: Mon, 7 Jul 2025 15:01:06 +1000 Subject: [PATCH 6/9] disable thingies again --- offlineASL-scala/build.mill | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/offlineASL-scala/build.mill b/offlineASL-scala/build.mill index 1cd6a096..b06fb124 100644 --- a/offlineASL-scala/build.mill +++ b/offlineASL-scala/build.mill @@ -5,7 +5,6 @@ package build import mill._, scalalib._, publish._ -import build.millfiles.SonatypeCentralPublishModule import mill.contrib.artifactory.ArtifactoryPublishModule object lifter extends ScalaModule with ArtifactoryPublishModule { @@ -16,13 +15,13 @@ object lifter extends ScalaModule with ArtifactoryPublishModule { override def publishVersion = "0.1.0" - // override def docSources = Seq[PathRef]() + override def docSources = Seq[PathRef]() override def pomSettings = PomSettings( description = "ASLp Offline Scala Lifter", organization = "io.github.uq-pac", url = "https://github.com/UQ-PAC/aslp", - licenses = Seq(License.MIT), + licenses = Seq(License.`BSD-3-Clause`), versionControl = VersionControl.github("UQ-PAC", "aslp"), developers = Seq(Developer("katrinafyi", "rina", "https://github.com/katrinafyi")) ) From f45319a29345733703d3f50e353fca663b7136c6 Mon Sep 17 00:00:00 2001 From: rina Date: Mon, 7 Jul 2025 15:02:24 +1000 Subject: [PATCH 7/9] generated --- .gitattributes | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitattributes b/.gitattributes index 1745a091..d070f9fe 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,5 +3,5 @@ *.t linguist-vendored *.asl linguist-vendored dune.generated linguist-generated -mill linguist-vendored -mill.bat linguist-vendored +mill linguist-generated +mill.bat linguist-generated From e106f53dc11846aebc75d8140fcb44c34b3e2342 Mon Sep 17 00:00:00 2001 From: rina Date: Mon, 7 Jul 2025 16:08:18 +1000 Subject: [PATCH 8/9] fix ci with ./mill --- .github/workflows/test.yml | 11 +++++------ offlineASL-scala/build.mill | 6 +++--- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ba92534c..bbd456da 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -103,15 +103,14 @@ jobs: - uses: cachix/install-nix-action@v25 - run: echo 'preparing nix shell environment' - - uses: coursier/cache-action@v6 - - uses: coursier/setup-action@v1 + - uses: actions/setup-java@v4 with: - jvm: adoptium:1.17 - apps: mill + distribution: 'temurin' + java-version: '17' - run: dune build --profile release - run: mkdir -p offlineASL-scala/lifter/src/generated - run: echo ':gen A64 .* scala true offlineASL-scala/lifter/src/generated' | OCAMLRUNPARAM=b dune exec asli - - run: 'cd offlineASL-scala && mill lifter.assembly' - - run: 'cd offlineASL-scala && mill main.run --help' + - run: 'cd offlineASL-scala && ./mill lifter.assembly' + - run: 'cd offlineASL-scala && ./mill main.run --help' diff --git a/offlineASL-scala/build.mill b/offlineASL-scala/build.mill index b06fb124..273131ce 100644 --- a/offlineASL-scala/build.mill +++ b/offlineASL-scala/build.mill @@ -8,7 +8,7 @@ import mill._, scalalib._, publish._ import mill.contrib.artifactory.ArtifactoryPublishModule object lifter extends ScalaModule with ArtifactoryPublishModule { - override def scalaVersion = "3.3.6" + override def scalaVersion = "3.3.4" override def artifactoryUri = "https://maven.pkg.github.com/UQ-PAC/aslp" override def artifactorySnapshotUri: String = artifactoryUri @@ -23,12 +23,12 @@ object lifter extends ScalaModule with ArtifactoryPublishModule { url = "https://github.com/UQ-PAC/aslp", licenses = Seq(License.`BSD-3-Clause`), versionControl = VersionControl.github("UQ-PAC", "aslp"), - developers = Seq(Developer("katrinafyi", "rina", "https://github.com/katrinafyi")) + developers = Seq(Developer("uqpac", "UQ PAC", "https://github.com/UQ-PAC")) ) } object main extends ScalaModule { - override def scalaVersion = "3.3.6" + override def scalaVersion = "3.3.4" override def moduleDeps = Seq(lifter) From 79185570602c5197e6e100c7142f204f4752cbc5 Mon Sep 17 00:00:00 2001 From: rina Date: Mon, 7 Jul 2025 16:46:34 +1000 Subject: [PATCH 9/9] use ./mill --- offlineASL-scala/readme.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/offlineASL-scala/readme.md b/offlineASL-scala/readme.md index b7e9e23f..57ff3aca 100644 --- a/offlineASL-scala/readme.md +++ b/offlineASL-scala/readme.md @@ -5,8 +5,8 @@ Requires Mill (e.g. installed by Coursier). Run in parent directory: mkdir -p offlineASL-scala/lifter/src/generated echo ':gen A64 aarch64.+ scala true offlineASL-scala/lifter/src/generated' | dune exec asli cd offlineASL-scala -mill lifter.assembly -mill main.run --opcode 0x8b031041 +./mill lifter.assembly +./mill main.run --opcode 0x8b031041 ``` This should compile successfully. However, the last command will fail since the default instruction-building interface simply throws "not implemented" @@ -18,9 +18,10 @@ The compiled offline lifter is uploaded to [Github Packages](https://github.com/orgs/UQ-PAC/packages?repo_name=aslp) which allows downstream projects to download it like any other Scala dependency. -To publish a new version, first increment `publishVersion` then run this command: +To publish a new version, first run the commands above. +Then, increment `publishVersion` and run this command: ```bash -./mill lifter.publishArtifactory --credentials katrinafyi:ghp_AAA +./mill lifter.publishArtifactory --credentials yourusername:ghp_AAA ``` You will need to get a `write:packages` Github classic token. See [the docs](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-apache-maven-registry).