cross-rs / cross

“Zero setup” cross compilation and “cross testing” of Rust crates
Apache License 2.0
6.53k stars 365 forks source link

Act: Build fails with `sh: 1: cargo: not found` #1321

Closed Sellig6792 closed 4 months ago

Sellig6792 commented 1 year ago

Hello, I've just finished the new version of my project. But when I did the PR an error occurred in the workflow. So I decided to revert the merge and tested the workflow locally with Act. Unfortunately, I discovered that, locally, I had one more error. For Information MacOS isn't running with Act.

The cross version is the v0.2.5

The Error

| [command]cross build --release --target x86_64-pc-windows-gnu
| info: downloading component 'rust-src'
| info: installing component 'rust-src'
| sh: 1: cargo: not found

The Job:

deploy_building:
  name: Deploy Building
  needs: [ test ]
  strategy:
    matrix:
      os: [ ubuntu-latest ] # Default os for build
      target: [ aarch64-unknown-linux-gnu,
                i686-pc-windows-gnu, x86_64-pc-windows-gnu,
                i686-unknown-linux-gnu, x86_64-unknown-linux-gnu,
                x86_64-apple-darwin ]
      exclude: # Do not build for macOS on Linux
        - target: x86_64-apple-darwin
          os: ubuntu-latest
      include:
        - target: x86_64-apple-darwin
          os: macos-latest
  # Runs on latest ubuntu by default except for windows targets
  runs-on: ${{ matrix.os }}
  steps:
    - name: Checkout
      uses: actions/checkout@v1
    - name: Install rust
      uses: actions-rs/toolchain@v1
      with:
        toolchain: stable
        profile: minimal
        override: true
        target: ${{ matrix.target }}
    - name: Build release
      uses: actions-rs/cargo@v1
      with:
        use-cross: true
        command: build
        args: --release --target ${{ matrix.target }}

Here is the verbose log for only one target (windows x86_64)

Thanks to all the people who will try to solve my problem

Emilgardis commented 1 year ago

you'll probably need CROSS_CONTAINER_IN_CONTAINER=true for act , act uses docker to containerize the actions and cross can't properly mount in those cases.

Pass in -v in the command to cross to see what it's doing.

Also, actions-rs is unmaintained, I'd highly recommend you find an alternative

Sellig6792 commented 1 year ago

I've already tried with CROSS_CONTAINER_IN_CONTAINER=true, I got this error:

| Error:
|    0: `docker inspect docker-desktop` failed with exit status: 1
|
| Stderr:
|    Error: No such object: docker-desktop
|
| Stdout:
|    []
[Develop PR/Deploy Building-1]   ❗  ::error::The process 'cross' failed with exit code 1
[Develop PR/Deploy Building-1]   ❌  Failure - Main Build release
[Develop PR/Deploy Building-1] exitcode '1': failure
[Develop PR/Deploy Building-1] 🏁  Job failed
Error: Job 'Deploy Building' failed

I didn't know that actions-rs was unmaintained, do you know an alternative for me ?

Emilgardis commented 1 year ago

I don't know how act works and I've never gotten it to work myself.

I suspect it's setting something weirdly, I'm not sure how to solve it Is it possible to use docker from within act?

The error comes from that it's not possible to re-mount inside a running container without access to the underlying filesystem. To get the path to the underlying fs we need to query docker for where the files actually live.

Another possible solution would be to use CROSS_REMOTE, see https://github.com/cross-rs/cross/wiki/FAQ#gitlab-ci

Emilgardis commented 1 year ago

This just reminded me, you might have to make act add -v /var/run/docker.sock:/var/run/docker.sock to the containers it spins

Sellig6792 commented 1 year ago

I didn't find anything about how to add -v to docker through act. Do you know how to do that ? Maybe I should open an issue on the repository of Act or edit and build Act myself...

Maximilian-Staab commented 1 year ago

Pretty sure this is a docker-in-docker-in-docker issue, at least it was in my case.

Basically cross tries to mount volumes into the the build container, but because cross/action-rs itself is running in a container, the mounts are relative to the act runner, not the container cross is called from.

I had to mount and use a volume like this:

jobs:
  your-job:
    container:
      volumes: # these have to be at this strange path, because the cross docker command will mount these volumes
        - /opt/repo:/opt/repo # can't be anonymous, because the volume will be deanonymized by cross

    steps:
      - name: Checkout repository
        uses: actions/checkout@v3
      - name: Copy repository for cross
        run: cp -a .. /opt/repo
      - name: Install cross-rs
        env: 
          CROSS_CONTAINER_IN_CONTAINER: true
        run: cargo install cross

      - name: Build Package
        working-directory: /opt/repo/snapper-rs
        env: 
          CROSS_CONTAINER_IN_CONTAINER: true
        run: cross build --release --target armv7-unknown-linux-gnueabihf -v

This is just an example, you need to install the rust toolchain as well.

If you use a Dockerfile for your cross build container, you need to install the rust toolchain in there manually. Usually the mounts would take care of that.

Sellig6792 commented 11 months ago

Pretty sure this is a docker-in-docker-in-docker issue, at least it was in my case.

Basically cross tries to mount volumes into the the build container, but because cross/action-rs itself is running in a container, the mounts are relative to the act runner, not the container cross is called from.

I had to mount and use a volume like this:

jobs:
  your-job:
    container:
      volumes: # these have to be at this strange path, because the cross docker command will mount these volumes
        - /opt/repo:/opt/repo # can't be anonymous, because the volume will be deanonymized by cross

    steps:
      - name: Checkout repository
        uses: actions/checkout@v3
      - name: Copy repository for cross
        run: cp -a .. /opt/repo
      - name: Install cross-rs
        env: 
          CROSS_CONTAINER_IN_CONTAINER: true
        run: cargo install cross

      - name: Build Package
        working-directory: /opt/repo/snapper-rs
        env: 
          CROSS_CONTAINER_IN_CONTAINER: true
        run: cross build --release --target armv7-unknown-linux-gnueabihf -v

This is just an example, you need to install the rust toolchain as well.

If you use a Dockerfile for your cross build container, you need to install the rust toolchain in there manually. Usually the mounts would take care of that.

Could you adapt it to my workflow ? Thanks

Sitin commented 10 months ago

Looks something is really wrong with CROSS_REMOTE.

I've created setup for CROSS_REMOTE similar to what GitLab uses by using Docker-in-Docker official image. It seems that cross in remote mode is messing with container layers and breaks containers. However, same target is built perfectly when cross is running without CROSS_REMOTE (also in Docker).

Results can be found in the gist.

You also can check the repo with code I've created for my experiments.