diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c9c3beb15..eb4355b9e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -57,18 +57,31 @@ jobs: # and upload them all to anaconda.org in a single job name: package-${{ github.sha }} path: ${{ runner.temp }}/conda-bld/*/*.tar.bz2 - - name: Run examples and prepare artifacts + - name: Install local constructor run: | source ../conda/etc/profile.d/conda.sh CONDA_BLD_PATH="${{ runner.temp }}/conda-bld" \ conda create -n constructor -c local --strict-channel-priority constructor conda activate constructor - installed_channel=$(conda list --json | jq -r '.[] | select(.name=="constructor") | .channel') + installed_channel=$(conda list constructor --json | jq -r '.[].channel') if [[ "$installed_channel" != "conda-bld" ]]; then - echo $(conda list --json | jq '.[] | select(.name=="constructor")') + echo $(conda list constructor --json) echo "Installed constructor is not local!" exit 1 fi + - name: Patch NSIS to use logging builds on Windows + if: startsWith(matrix.os, 'windows') + run: | + source ../conda/etc/profile.d/conda.sh + conda activate constructor + nsis_version=$(conda list nsis --json | jq -r ".[].version") + curl -sL "https://sourceforge.net/projects/nsis/files/NSIS%203/${nsis_version}/nsis-${nsis_version}-log.zip/download" -o "nsis-${nsis_version}-log.zip" + 7z x "nsis-${nsis_version}-log.zip" -aoa -o"$CONDA_PREFIX/NSIS/" + echo "NSIS_USING_LOG_BUILD=1" >> $GITHUB_ENV + - name: Run examples and prepare artifacts + run: | + source ../conda/etc/profile.d/conda.sh + conda activate constructor mkdir -p examples_artifacts/ python scripts/run_examples.py --keep-artifacts=examples_artifacts/ - name: Upload the example installers as artifacts diff --git a/constructor/nsis/main.nsi.tmpl b/constructor/nsis/main.nsi.tmpl index 83c37db98..444f515cb 100644 --- a/constructor/nsis/main.nsi.tmpl +++ b/constructor/nsis/main.nsi.tmpl @@ -5,6 +5,27 @@ Unicode "true" +#if enable_debugging is True +# Special logging build needed for ENABLE_LOGGING +# See https://nsis.sourceforge.io/Special_Builds +!define ENABLE_LOGGING +#endif + +# Comes from https://nsis.sourceforge.io/Logging:Enable_Logs_Quickly +!define LogSet "!insertmacro LogSetMacro" +!macro LogSetMacro SETTING + !ifdef ENABLE_LOGGING + LogSet ${SETTING} + !endif +!macroend + +!define LogText "!insertmacro LogTextMacro" +!macro LogTextMacro INPUT_TEXT + !ifdef ENABLE_LOGGING + LogText ${INPUT_TEXT} + !endif +!macroend + !include "WinMessages.nsh" !include "WordFunc.nsh" !include "LogicLib.nsh" @@ -414,6 +435,7 @@ Function InstModePage_Leave FunctionEnd Function .onInit + ${LogSet} on Push $0 Push $1 Push $2 @@ -835,6 +857,7 @@ Function AbortRetryNSExecWait nsExec::ExecToLog $2 pop $0 ${If} $0 != "0" + DetailPrint "::error:: $1" MessageBox MB_ABORTRETRYIGNORE|MB_ICONEXCLAMATION|MB_DEFBUTTON3 \ $1 /SD IDIGNORE IDABORT abort IDRETRY retry ; IDIGNORE: Continue anyway @@ -851,6 +874,7 @@ FunctionEnd # Installer sections Section "Install" + ${LogSet} on SetOutPath "$INSTDIR\Lib" File "@NSIS_DIR@\_nsis.py" @@ -893,6 +917,13 @@ Section "Install" @PKG_COMMANDS@ + SetDetailsPrint TextOnly + DetailPrint "Setting up the package cache ..." + push '"$INSTDIR\_conda.exe" constructor --prefix "$INSTDIR" --extract-conda-pkgs' + push 'Failed to extract packages' + call AbortRetryNSExecWait + SetDetailsPrint both + @SETUP_ENVS@ @WRITE_CONDARC@ @@ -906,9 +937,12 @@ Section "Install" call AbortRetryNSExecWait ${EndIf} +#if has_conda is True + DetailPrint "Initializing conda directories..." push '"$INSTDIR\pythonw.exe" -E -s "$INSTDIR\Lib\_nsis.py" mkdirs' - push 'Failed to initialize Anaconda directories' + push 'Failed to initialize conda directories' call AbortRetryNSExecWait +#endif ${If} $Ana_PostInstall_State = ${BST_CHECKED} DetailPrint "Running post install..." diff --git a/constructor/winexe.py b/constructor/winexe.py index a53fa03ae..a1a826a01 100644 --- a/constructor/winexe.py +++ b/constructor/winexe.py @@ -68,17 +68,21 @@ def setup_envs_commands(info, dir_path): SetDetailsPrint both # List of packages to install SetOutPath "{env_txt_dir}" - File {env_txt_abspath} + File "{env_txt_abspath}" # A conda-meta\history file is required for a valid conda prefix SetOutPath "{conda_meta}" - FileOpen $0 "history" w - FileClose $0 + File "{history_abspath}" # Set channels System::Call 'kernel32::SetEnvironmentVariable(t,t)i("CONDA_CHANNELS", "{channels}").r0' # Run conda SetDetailsPrint TextOnly nsExec::ExecToLog '"$INSTDIR\_conda.exe" install --offline -yp "{prefix}" --file "{env_txt}" {shortcuts}' Pop $0 + ${{If}} $0 != "0" + DetailPrint "::error:: Failed to link extracted packages to {prefix}!" + MessageBox MB_OK|MB_ICONSTOP "Failed to link extracted packages to {prefix}. Please check logs." /SD IDOK + Abort + ${{EndIf}} SetDetailsPrint both # Cleanup {name} env.txt SetOutPath "$INSTDIR" @@ -86,7 +90,7 @@ def setup_envs_commands(info, dir_path): # Restore shipped conda-meta\history for remapped # channels and retain only the first transaction SetOutPath "{conda_meta}" - File {history_abspath} + File "{history_abspath}" """ lines = template.format( # this one block is for the base environment @@ -194,6 +198,8 @@ def make_nsi(info, dir_path, extra_files=()): ppd['keep_pkgs'] = info.get('keep_pkgs') or False ppd['post_install_exists'] = bool(info.get('post_install')) ppd['with_conclusion_text'] = bool(conclusion_text) + ppd["enable_debugging"] = bool(os.environ.get("NSIS_USING_LOG_BUILD")) + ppd["has_conda"] = info["_has_conda"] data = preprocess(data, ppd) data = fill_template(data, replace) if info['_platform'].startswith("win") and sys.platform != 'win32': diff --git a/news/553-fix-windows-ci b/news/553-fix-windows-ci new file mode 100644 index 000000000..f14adc7f3 --- /dev/null +++ b/news/553-fix-windows-ci @@ -0,0 +1,25 @@ +Enhancements: +------------- + +* A single installer can now provide multiple environments through the `extra_envs` key (#359 via #509 and #553) + +Bug fixes: +---------- + +* Windows CI now correctly detects installation problems (#551) + +Deprecations: +------------- + +* + +Docs: +----- + +* + +Other: +------ + +* + diff --git a/scripts/run_examples.py b/scripts/run_examples.py index 09eee5143..688b5348a 100644 --- a/scripts/run_examples.py +++ b/scripts/run_examples.py @@ -102,6 +102,14 @@ def run_examples(keep_artifacts=None): elif ext == 'exe': cmd = ['cmd.exe', '/c', 'start', '/wait', fpath, '/S', '/D=%s' % env_dir] test_errored = _execute(cmd) + if ext == 'exe' and os.environ.get("NSIS_USING_LOG_BUILD"): + test_errored = 0 + with open(os.path.join(env_dir, "install.log"), encoding="utf-16-le") as f: + print('--- LOGS ---') + for line in f: + if ":error:" in line: + print(line.rstrip()) + test_errored = 1 errored += test_errored if keep_artifacts: shutil.move(fpath, keep_artifacts)