Closed UweKeim closed 1 year ago
Uwe, I suspect that it is that the current CS-Script package probing algorithm is failing. Can you check if that test script from #326 identifies the package assembly correctly?
If it does then I can prioritize its integration with the codebase.
Note, that you may need to update the packages repo path:
var nugetRepo =
Environment.OSVersion.Platform == PlatformID.Win32NT ?
Environment.ExpandEnvironmentVariables(@"%userprofile%\.nuget\packages") :
"~/.nuget/packages";
Thank you, Oleg!
I've run the script in a new CI/CD job with this result:
...
$ dotnet $CSCS_EXE_FILEPATH ${CI_PROJECT_DIR}/Etc/Testing/testscript-for-oleg.cs
/root/.local/share/Temp/csscript.core/nuget/349af62d-da05-42cb-a458-d910843[20](https://git.zeta-sw.com/zeta/zeta-shared-ci-assets/-/jobs/1513#L20)791/nuget.ref.csproj
Restoring packages...
00:00:03.0717686
Mapping packages to assemblies...
================
Could not find a part of the path '/builds/zeta/zeta-shared-ci-assets/Etc/Testing/~/.nuget/packages'.
System.IO.DirectoryNotFoundException: Could not find a part of the path '/builds/zeta/zeta-shared-ci-assets/Etc/Testing/~/.nuget/packages'.
at System.IO.Enumeration.FileSystemEnumerator`1.CreateDirectoryHandle(String path, Boolean ignoreNotFound)
at System.IO.Enumeration.FileSystemEnumerator`1.Init()
at System.IO.Enumeration.FileSystemEnumerable`1..ctor(String directory, FindTransform transform, EnumerationOptions options, Boolean isNormalized)
at System.IO.Enumeration.FileSystemEnumerableFactory.UserDirectories(String directory, String expression, EnumerationOptions options)
at System.IO.Directory.InternalEnumeratePaths(String path, String searchPattern, SearchTarget searchTarget, EnumerationOptions options)
at System.IO.Directory.GetDirectories(String path, String searchPattern, EnumerationOptions enumerationOptions)
at Program.<Main>$(String[] args)
Unhandled exception. System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
---> System.IO.DirectoryNotFoundException: Could not find a part of the path '/builds/zeta/zeta-shared-ci-assets/Etc/Testing/~/.nuget/packages'.
at System.IO.Enumeration.FileSystemEnumerator`1.CreateDirectoryHandle(String path, Boolean ignoreNotFound)
at System.IO.Enumeration.FileSystemEnumerator`1.Init()
at System.IO.Enumeration.FileSystemEnumerable`1..ctor(String directory, FindTransform transform, EnumerationOptions options, Boolean isNormalized)
at System.IO.Enumeration.FileSystemEnumerableFactory.UserDirectories(String directory, String expression, EnumerationOptions options)
at System.IO.Directory.InternalEnumeratePaths(String path, String searchPattern, SearchTarget searchTarget, EnumerationOptions options)
at System.IO.Directory.GetDirectories(String path, String searchPattern, EnumerationOptions enumerationOptions)
at Program.<Main>$(String[] args)
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
--- End of inner exception stack trace ---
at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at csscript.LocalExecutor.InvokeStaticMain(Assembly compiledAssembly, String[] scriptArgs)
at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__1[28](https://git.zeta-sw.com/zeta/zeta-shared-ci-assets/-/jobs/1513#L28)_1(Object state)
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()
/bin/bash: line 1[40](https://git.zeta-sw.com/zeta/zeta-shared-ci-assets/-/jobs/1513#L40): 12 Aborted (core dumped) dotnet $CSCS_EXE_FILEPATH ${CI_PROJECT_DIR}/Etc/Testing/testscript-for-oleg.cs
I've changed the var nugetRepo = ...
part to this:
var nugetRepo =
Environment.OSVersion.Platform == PlatformID.Win32NT ?
Environment.ExpandEnvironmentVariables(@"%userprofile%\.nuget\packages") :
"/tmp/.nuget/packages";
Directory.CreateDirectory(nugetRepo); // Added this one, too!
Then it ran without errors:
$ dotnet $CSCS_EXE_FILEPATH ${CI_PROJECT_DIR}/Etc/Testing/testscript-for-oleg.cs
/root/.local/share/Temp/csscript.core/nuget/17494f34-6482-4e4c-9d70-926e1a842d26/nuget.ref.csproj
Restoring packages...
00:00:03.0874076
Mapping packages to assemblies...
================
================
00:00:00.0064136
But still did not find the MoreLinq
repo, even with the brute force directory checking with "*".
OK, I completely misunderstood the meaning of nugetRepo
. After reading this Stack Overflow answer I did this:
var nugetRepo =
Environment.OSVersion.Platform == PlatformID.Win32NT ?
Environment.ExpandEnvironmentVariables(@"%userprofile%\.nuget\packages") :
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "/.nuget/packages";
This seems to be the right thing as it now prints:
$ dotnet $CSCS_EXE_FILEPATH ${CI_PROJECT_DIR}/Etc/Testing/testscript-for-oleg.cs
/root/.local/share/Temp/csscript.core/nuget/f63013c5-bb50-4434-916a-b9f5e89b232f/nuget.ref.csproj
Restoring packages...
00:00:03.5686736
Mapping packages to assemblies...
================
/root/.nuget/packages/morelinq/3.4.1/lib/net6.0/MoreLinq.dll
================
00:00:00.0097046
To further simplify the nugetRepo
variable, a platform agnostic way could be to write it as something like that:
var nugetRepo =
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".nuget", "packages");
That is a perfect result. Great. Will try to come up with a working solution over the weekend
But I would still allow custom location just in case:
var nugetRepo =
Environment.GetEnvironmentVariable("CSS_CUSTOM_NUGET_REPO") ??
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".nuget", "packages");
This could come up super helpful! Great idea! โฅ๏ธ
Don't know whether this is relevant here; the documentation says that you can define a custom nuget.config
file in the root of a project repository with an optional globalPackagesFolder
entry. To quote:
The location of the default global packages folder. The default is
%userprofile%\.nuget\packages
(Windows) or~/.nuget/packages
(Mac/Linux). A relative path can be used in project-specificnuget.config
files. This setting is overridden by theNUGET_PACKAGES
environment variable, which takes precedence.
I don't need this feature, I just wanted to document it here, in case someone is looking it up some time in the future ๐.
Or maybe the NUGET_PACKAGES
environment variable could be queried, too? Like e.g.:
var nugetRepo =
Environment.GetEnvironmentVariable("CSS_CUSTOM_NUGET_REPO") ??
Environment.GetEnvironmentVariable("NUGET_PACKAGES") ??
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".nuget", "packages");
Just an idea.
Done. Have a look at https://github.com/oleg-shilo/cs-script/releases/tag/v4.6.5.2-rc2
Thank you very much, Oleg!
I've tried this script ("cicd-test-02.cs") again:
//css_nuget -force:3600 Newtonsoft.Json
using System;
using Newtonsoft.Json;
public static class Processor
{
public static int Main()
{
Console.WriteLine("Hello from cicd-test-02.cs");
var json = JsonConvert.SerializeObject(new { success = true } );
Console.WriteLine(json);
return 0;
}
}
Running with v4.6.5.2-rc2 on my Windows 11 machine succeeds and prints this:
Hello from cicd-test-02.cs
{"success":true}
Running with v4.6.5.2-rc2 inside an Ubuntu GitLab Runner fails with these messages:
$ dotnet /builds/zeta/zeta-shared-ci-assets/DevelopmentTools/cs-script-linux/cscs.dll /builds/zeta/zeta-shared-ci-assets/Etc/Testing/cicd-test-02.cs
NuGet> Processing NuGet packages...
Determining projects to restore...
Writing /tmp/tmpXPmxnr.tmp
info : X.509 certificate chain validation will use the fallback certificate bundle at '/usr/share/dotnet/sdk/7.0.202/trustedroots/codesignctl.pem'.
info : X.509 certificate chain validation will use the fallback certificate bundle at '/usr/share/dotnet/sdk/7.0.202/trustedroots/timestampctl.pem'.
info : Adding PackageReference for package 'Newtonsoft.Json' into project '/tmp/csscript.core/.nuget/23/23.csproj'.
info : GET https://api.nuget.org/v3/registration5-gz-semver2/newtonsoft.json/index.json
info : OK https://api.nuget.org/v3/registration5-gz-semver2/newtonsoft.json/index.json 119ms
info : Restoring packages for /tmp/csscript.core/.nuget/23/23.csproj...
info : GET https://api.nuget.org/v3-flatcontainer/newtonsoft.json/index.json
info : OK https://api.nuget.org/v3-flatcontainer/newtonsoft.json/index.json 121ms
info : GET https://api.nuget.org/v3-flatcontainer/newtonsoft.json/13.0.3/newtonsoft.json.13.0.3.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/newtonsoft.json/13.0.3/newtonsoft.json.13.0.3.nupkg 14ms
info : Installed Newtonsoft.Json 13.0.3 from https://api.nuget.org/v3/index.json with content hash HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==.
info : Package 'Newtonsoft.Json' is compatible with all the specified frameworks in project '/tmp/csscript.core/.nuget/23/23.csproj'.
info : PackageReference for package 'Newtonsoft.Json' version '13.0.3' added to file '/tmp/csscript.core/.nuget/23/23.csproj'.
info : Writing assets file to disk. Path: /tmp/csscript.core/.nuget/23/obj/project.assets.json
log : Restored /tmp/csscript.core/.nuget/23/23.csproj (in 4[33](https://git.zeta-sw.com/zeta/zeta-shared-ci-assets/-/jobs/1542#L33) ms).
Error: Specified file could not be compiled.
> -----
A new NuGet package has been installed. If some of its components are not found you may need to restart the script again.
> -----
Cannot process NuGet package 'Newtonsoft.Json'
Basically, from the above excerpt, my command line is:
dotnet /builds/zeta/zeta-shared-ci-assets/DevelopmentTools/cs-script-linux/cscs.dll /builds/zeta/zeta-shared-ci-assets/Etc/Testing/cicd-test-02.cs
Maybe I'm calling CS-Script wrong?
Is there anything other way I can assist on debugging/resolving this?
I could as well set up a Ubuntu Server VM and test my scripts inside this one, too. So no testing in a Docker container but a full Ubuntu, in case this would help?
I've tried to add the -dbg
switch to the CS-Script call:
$ dotnet $CSCS_EXE_FILEPATH -dbg ${CI_PROJECT_DIR}/Etc/Testing/cicd-test-02.cs
NuGet> Processing NuGet packages...
Determining projects to restore...
Writing /tmp/tmpityRfC.tmp
info : X.509 certificate chain validation will use the fallback certificate bundle at '/usr/share/dotnet/sdk/7.0.202/trustedroots/codesignctl.pem'.
info : X.509 certificate chain validation will use the fallback certificate bundle at '/usr/share/dotnet/sdk/7.0.202/trustedroots/timestampctl.pem'.
info : Adding PackageReference for package 'Newtonsoft.Json' into project '/tmp/csscript.core/.nuget/12/12.csproj'.
info : GET https://api.nuget.org/v3/registration5-gz-semver2/newtonsoft.json/index.json
info : OK https://api.nuget.org/v3/registration5-gz-semver2/newtonsoft.json/index.json 126ms
info : Restoring packages for /tmp/csscript.core/.nuget/12/12.csproj...
info : GET https://api.nuget.org/v3-flatcontainer/newtonsoft.json/index.json
info : OK https://api.nuget.org/v3-flatcontainer/newtonsoft.json/index.json 437ms
info : GET https://api.nuget.org/v3-flatcontainer/newtonsoft.json/13.0.3/newtonsoft.json.13.0.3.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/newtonsoft.json/13.0.3/newtonsoft.json.13.0.3.nupkg [24](https://git.zeta-sw.com/zeta/zeta-shared-ci-assets/-/jobs/1546#L24)ms
info : Installed Newtonsoft.Json 13.0.3 from https://api.nuget.org/v3/index.json with content hash HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==.
info : Package 'Newtonsoft.Json' is compatible with all the specified frameworks in project '/tmp/csscript.core/.nuget/12/12.csproj'.
info : PackageReference for package 'Newtonsoft.Json' version '13.0.3' added to file '/tmp/csscript.core/.nuget/12/12.csproj'.
info : Writing assets file to disk. Path: /tmp/csscript.core/.nuget/12/obj/project.assets.json
log : Restored /tmp/csscript.core/.nuget/12/12.csproj (in 906 ms).
Error: Specified file could not be compiled.
> -----
A new NuGet package has been installed. If some of its components are not found you may need to restart the script again.
> -----
Cannot process NuGet package 'Newtonsoft.Json'
Don't know whether this help, as it doesn't seem to add more output.
The message Processing NuGet packages....
is only printed with the legacy NuGet support. Meaning that the new algorithm is not enabled in your environment.
Is it possible that you forgot to enable the new nuget algorithm?
css -config:set:LegacyNugetSupport=false
By default it is disabled.
BTW -force:3600
will be ignored in the new approach. Please read about it here: https://github.com/oleg-shilo/cs-script/wiki/NuGet-Support
OMG, shame on me! I did not even understand that I have to call this.
I've successfully tried to manage this on Windows, since there is a "css.exe".
For Linux, I've done it this way (since the css
alias doesn't seem to work):
$ dotnet $CSCS_EXE_FILEPATH -config:set:LegacyNugetSupport=false
set: LegacyNugetSupport: False
$ dotnet $CSCS_EXE_FILEPATH -dbg ${CI_PROJECT_DIR}/Etc/Testing/cicd-test-02.cs
Restoring packages...
Mapping packages to assemblies1111...
Hello from cicd-test-02.cs
{"success":true}
(I.e. calling cscs.dll
instead of css
).
And this also worked! Awesome ๐๐
You've made my sunday!
Yey!!! Will prepare the official release asap
I will also publish it as a .NET tool.
Meaning that you will be able to use it with css
alias (https://github.com/oleg-shilo/cs-script/issues/317#issuecomment-1484062299)
I tested it already on Win but expect Linux to do the same.
Thank you!
So instead of manually downloading the 7z files with CS-Script for Linux and Windows, I simply can do on both platforms a
dotnet tool install --global cs-script.cli
And always have the latest version?
That would be hell of an improvement over my current workflow.
Yep. Choc does the same but it is not available on Linux. On Linux, you have to use
In Ubuntu terminal:
repo=https://github.com/oleg-shilo/cs-script/releases/download/v4.6.5.0/; file=cs-script_4.6-5.deb; rm $file; wget $repo$file; sudo dpkg -i $file
Depending on the user context you may need to add permissions to the CS-Script temp dir sudo chmod -R 777 /tmp
Obviously having the same distribution channel (dotnet) on all OSs is a preferred approach.
The only thing that you need to do manually is to stop any running instance of the script engine: css -servers:stop
Cocho can do it automatically but dotnet
cannot :(
yes the "get latest version" command will be something like that:
css -servers:stop
dotnet tool update --global cs-script.cli
Since my CI/CD jobs fire up a new Docker image upon every run, I guess I do not have to do the stopping at all.
Will be happy to test as soon as it is released โฅ๏ธ.
Thanks a million times for all your help!
Not only is the CS-Script engine superior to all the other .NET scripting engines out there in terms of features, but what makes it outstanding is your awesome, dedicated support!
Not a prob :o)
Done. Release v4.7.0
You can install it as a the tool now: https://www.nuget.org/packages/cs-script.cli
Thank you very much, Oleg.
On Windows, I can now run my scripts successfully via:
css my-script.css
In my GitLab runner, after executing these scripts successfully:
dotnet tool install --global cs-script.cli
dotnet tool update --global cs-script.cli
I tried different ways to call CS-Script, all of them failed with "command not found" or similar errors:
css my-script.cs
cscs my-script.cs
dotnet css my-script.cs
dotnet css.exe my-script.cs
dotnet cscs my-script.cs
dotnet cscs.dll my-script.cs
Do you have any idea on how I could call it successfully inside my Ubuntu GitLab Runner?
I've fired up an Ubuntu 22 Server (Ubuntu 22.04.2 LTS), installed .NET SDK 7 and then installed CS-Script via dotnet tool update --global cs-script.cli
:
root@server:/home/ukeim# dotnet tool update --global cs-script.cli
Welcome to .NET 7.0!
---------------------
SDK Version: 7.0.202
Telemetry
---------
The .NET tools collect usage data in order to help us improve your experience. It is collected by Microsoft and shared with the community. You can opt-out of telemetry by setting the DOTNET_CLI_TELEMETRY_OPTOUT environment variable to '1' or 'true' using your favorite shell.
Read more about .NET CLI Tools telemetry: https://aka.ms/dotnet-cli-telemetry
----------------
Installed an ASP.NET Core HTTPS development certificate.
To trust the certificate run 'dotnet dev-certs https --trust' (Windows and macOS only).
Learn about HTTPS: https://aka.ms/dotnet-https
----------------
Write your first app: https://aka.ms/dotnet-hello-world
Find out what's new: https://aka.ms/dotnet-whats-new
Explore documentation: https://aka.ms/dotnet-docs
Report issues and find source on GitHub: https://github.com/dotnet/core
Use 'dotnet --help' to see available commands or visit: https://aka.ms/dotnet-cli
--------------------------------------------------------------------------------------
You can invoke the tool using the following command: css
Tool 'cs-script.cli' (version '4.7.0') was successfully installed.
Next, I tried a simple css
call:
root@server:/home/ukeim# css
Command 'css' not found, but there are 16 similar ones.
I've also tried all other variations of the command like dotnet css
, cscs
, cscs.exe
, css.exe
, css.dll
etc. without any success.
So it seems that this is not just an issue inside a CI/CD Ubuntu Docker GitLab Runner but also on a full Ubuntu system.
I was able to locate css
at ~/.dotnet/tools/css
.
So with this information I was able to run it this way:
root@server:~/.dotnet/tools# ~/.dotnet/tools/css
C# Script execution engine (.NET Core). Version 4.7.0.0.
Copyright (C) 2004-2020 Oleg Shilo. www.csscript.net (github.com/oleg-shilo/cs-script)
CLR: 7.0.4
System: Unix 5.15.0.67
Architecture: x64
Script engine: /root/.dotnet/tools/.store/cs-script.cli/4.7.0/cs-script.cli/4.7.0/tools/net7.0/any/cscs.dll
Compiler engine: csc (/usr/share/dotnet/sdk/7.0.202/Roslyn/bincore/csc.dll)
-> dotnet (/usr/share/dotnet/dotnet)
NuGet manager: dotnet
NuGet cache: <not found>
Custom commands: /usr/share/cs-script/commands
Global includes: /usr/share/cs-script/inc
Not sure whether it is intended to run it with the absolute path only, but at least it seems to run now ๐๐
I'll try something similar now in my CI/CD script.
Yes, my CI/CD job now runs successfully:
image: mcr.microsoft.com/dotnet/sdk:latest
default:
tags:
- ubuntu
stages:
- tests-01
tests-01:
stage: tests-01
script:
- dotnet tool install --global cs-script.cli
- dotnet tool update --global cs-script.cli
- ~/.dotnet/tools/css -config:set:LegacyNugetSupport=false
- ~/.dotnet/tools/css ${CI_PROJECT_DIR}/Etc/Testing/cicd-test-01.cs
- ~/.dotnet/tools/css ${CI_PROJECT_DIR}/Etc/Testing/cicd-test-02.cs
- ~/.dotnet/tools/css ${CI_PROJECT_DIR}/Etc/Testing/cicd-test-03.cs
All three tests scripts "cicd-test-01.cs", "cicd-test-02.cs", "cicd-test-03.cs" run without errors.
Thank you Uwe,
I am still discovering ".NET Tool" insights and at the moment I was only able to check how it works on Windows.
Linux is yet to come and my assumption is that it offers the identical functionality as Win. Judging from your report it is not the case. On Win I was able to call css
right after the installation.
It does look like an oversight from the SDK team. Though there is an interesting defect opened from 2018. Exactly about that: https://github.com/dotnet/dotnet-docker/issues/520
As for your situation, you probably can fix it by adding /root/.dotnet/tools/
to system PATH.
Or you can create an alias alias css='/root/.dotnet/tools/css'
. Now you can just call css and it will run it from the right path.
If you want to make this change permanent you can do this:
echo "alias css=' /root/.dotnet/tools/csc'" >> ~/.bashrc
source ~/.bashrc
Alternatively, you can add
RUN echo "PATH=/m:ybin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/.dotnet/tools
" > /etc/environment
to your dockerfile See https://stackoverflow.com/questions/67849660/how-to-set-system-wide-path-in-ubuntu20-04-docker-image discussion
The whole idea of ".NET Tool" is more attractive for vendors because:
But it comes with a price. You cannot have any behaviour executed either before or after installation.
With Choco, you can, and with Choco deployment, CS-Script tool package sets the PATH after installation. But for dotnet-tool on Linux it needs to be done manually.
Thanks, Oleg โฅ๏ธ
Using ~/.dotnet/tools/css
seems to be totally working and is absolutely sufficient for my use cases.
Currently I'm trying to use a CS-Script with a Docker GitLab Runner running my CI/CD job inside a Docker image with latest .NET SDK.
I was able to successfully run a small script that basically prints out "Hello world".
What I'm failing currently is to use a real-world script with NuGet references.
Here are the last few lines of a failed GitLab Runner job:
I'm not quite sure what's going on, but could imagine that those absolute paths starting at "
/tmp/csscript.core/.nuget/...
" are something that is not possible inside a runner.Basically my repository is checked out by the runner into something like:
Where "
build
" is the root and the other folders are my GitLab group and GitLab repository name.My questions
/tmp/csscript.core/...
" is right, is there a way to tell CS-Script another base folder?It seems that this issue over on the GitLab forum seems to be related and they tell not to use
/tmp
, if I understand them correctly.Would be great if you could help me on making CS-Script run in a Docker CI/CD job ๐.
Update 1
I've added some bash commands to my GitLab CI/CD script's job to write to "
/tmp
" and this seemed to work:So creating a directory and a file seems to work in general, maybe my above assumption was a red herring.
This leaves me totally clueless for now what might be the cause of CS-Script failing to handle the NuGet packages.
Update 2
This is a minimal CS-Script script that runs successfully locally on my Windows machine with the Windows version of CS-Script and also runs successfully inside my Docker CI/CD image with the Linux version of CS-Script:
This is a minimal CS-Script script that runs successfully locally on my Windows machine with the Windows version of CS-Script and fails to run inside my Docker CI/CD image with the Linux version of CS-Script:
The error that is printed from the runner is:
Just for completeness here is my ".gitlab-ci.yml" file with the definitions: