workflow / nix-shell-action

Run any command you like in a deterministic Nix shell on Linux and macOS.
MIT License
38 stars 10 forks source link

Actions does not behave the same way as `nix-shell` command #331

Open kha20240826 opened 1 week ago

kha20240826 commented 1 week ago

Using your action

- name: Test with java
  uses: workflow/nix-shell-action@v3
  with:
    packages: maven,jdk11_headless
    script: |
      java --version;
      mvn --version;

Got me

openjdk 11.0.23 2024-04-16
OpenJDK Runtime Environment (build 11.0.23+0-adhoc..source)
OpenJDK 64-Bit Server VM (build 11.0.23+0-adhoc..source, mixed mode)

Apache Maven 3.9.8 (36645f6c9b5079805ea5009217e36f2cffd34256)
Maven home: /nix/store/6y2p26qfy6qqzrl0wjvdz0hdc6lyl5jy-maven-3.9.8/maven
Java version: 21.0.3, vendor: N/A, runtime: /nix/store/z0hakcf7s1r4wfmwkk6z44wx9b7qfgp3-openjdk-headless-21.0.3+9/lib/openjdk
Default locale: en_US, platform encoding: UTF-8

My maven java version is set to 21 as my jdk version is 11 as the one passed in the packages parameter.

When I'm running the following in my terminal

$ nix-shell -p maven jdk11_headless
$ java --version
$ mvn --version

I got the following result

openjdk 11.0.23 2024-04-16
OpenJDK Runtime Environment (build 11.0.23+0-adhoc..source)
OpenJDK 64-Bit Server VM (build 11.0.23+0-adhoc..source, mixed mode)

pache Maven 3.9.8 (36645f6c9b5079805ea5009217e36f2cffd34256)
Maven home: /nix/store/sf5lp0zlss0mqbzn68ii9qj3mhbf67zk-maven-3.9.8/maven
Java version: 11.0.23, vendor: Oracle Corporation, runtime: /nix/store/8vb9mnp3k0rg4n7bsqc9zqplmyyjs9fc-openjdk-headless-11.0.23+9/lib/openjdk
Default locale: en, platform encoding: UTF-8

Maven java version running in terminal does match the jdk11_headless passing to the command line, if I take maven alone I got jdk21 in my nix shell.

Maybe I don't really understand how nix is supposed to work (I'm a bit new to it) but from my point of view it would have been logical that using this action should have the same behavior as when I'm launching a shell from my local environment.

workflow commented 1 week ago

Hi @kha20240826,

The way that maven seems to work is that it uses the JAVA_HOME env var to determine which version of the jdk to use. In your local reproduction you likely had no jdk installed in the background, but on the github runners, the existing version of the jdk will "bleed" into maven at execution time.

You can verify this locally by installing something like jdk21 on your system (or in an underlying nix shell), and then trying the nix-shell again.

There's probably a cleaner way to pin the Java version for Maven, with flakes or an overriden maven package, but this also works:

- name: Test with java
  uses: workflow/nix-shell-action@v3
  with:
    packages: maven,jdk11_headless
    script: |
      export JAVA_HOME=$(dirname $(dirname $(readlink -f $(which javac))));
      java --version;
      mvn --version;
workflow commented 1 week ago

A pure nix-shell (run with --pure) would also fix this, but that's probably not what most people want, as pure shells will have their own limitations in the context of the runner. I could make --pure an opt-in option though.

kha20240826 commented 1 week ago

Hi @workflow

Thanks for your answer, I can deal with the JAVA_HOME change!

But that's a bit weird because I'm self hosting the github runner on a local kube cluster and there's no java installed in the image at all (not even on the hosting machine...) :/

docker run --rm ghcr.io/actions/actions-runner:2.319.1 'java --version'

workflow commented 1 week ago

Hi @workflow

Thanks for your answer, I can deal with the JAVA_HOME change!

But that's a bit weird because I'm self hosting the github runner on a local kube cluster and there's no java installed in the image at all (not even on the hosting machine...) :/

docker run --rm ghcr.io/actions/actions-runner:2.319.1 'java --version'

That's interesting indeed and taking a closer look at your original snippet it looks like Java21 is coming from nixpkgs somehow :eyes:

I looked at the maven source in nixpkgs and saw that it takes a jdk argument, so you can also override it like so to make sure it's being built against the java version you want:

nix-shell -p jdk11_headless '(maven.override {jdk=jdk11;})'

...however if JAVA_HOME is set differently it will still default to that at runtime. (which shouldn't be the case on your runner, but double-check)

Anyways I think it makes sense to introduce a pure shell option here to prevent unexpected things like JAVA_HOME to bleed into our env, thank you for the inspiration to do that! edit: turns out getting a "pure" nix shell is harder with the new nix commands, played around a bit but couldn't get anything to work that still works as a decent shell.