Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: improve dependency installation in rust builder #232

Merged
merged 36 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
af424df
fix: update rust-base
bkioshn Apr 12, 2024
0f7f1d5
Merge branch 'master' into fix/improve-rust-builder
bkioshn Apr 12, 2024
7bb4b63
fix: revert back
bkioshn Apr 12, 2024
b65acdd
fix: update rust builder
bkioshn Apr 13, 2024
96a7ab6
fix: spelling
bkioshn Apr 13, 2024
1f63d83
fix: rust base
bkioshn Apr 14, 2024
53595a3
fix: refinery folder
bkioshn Apr 14, 2024
854bb31
fix: target
bkioshn Apr 14, 2024
fa8e001
fix: update wasm c earthfile
bkioshn Apr 14, 2024
29a4800
fix: cargo path name
bkioshn Apr 14, 2024
5a74c5f
fix: cleanup
bkioshn Apr 14, 2024
3dd886e
fix: update earthly version in rust example
bkioshn Apr 15, 2024
28d7c80
fix: cleanup
bkioshn Apr 15, 2024
6e26955
chore: fix rust docs
bkioshn Apr 15, 2024
4410cb5
fix: update rust installer
bkioshn Apr 15, 2024
e885373
fix: update earthly
bkioshn Apr 15, 2024
1b2717e
fix: remove name
bkioshn Apr 19, 2024
33761f5
Merge branch 'master' into fix/improve-rust-builder
bkioshn Apr 19, 2024
50f05c1
feat: add wasm-pack
bkioshn Apr 19, 2024
22177f7
fix: typo
bkioshn Apr 19, 2024
fc264ba
test: try lib/rust earthly
bkioshn Apr 29, 2024
6b58d94
fix: typo
bkioshn Apr 29, 2024
68ff8bb
fix: remove artifact name
bkioshn Apr 30, 2024
f6269c6
fix(rust-builders): Improve rust builder (#236)
stevenj May 3, 2024
62e2c54
fix: update docs
bkioshn May 3, 2024
fcce605
Revert docs changes
bkioshn May 4, 2024
18cb3cb
doc: update style doc
bkioshn May 4, 2024
d2e2449
doc: update rust doc
bkioshn May 5, 2024
c104c9a
doc: fix md style
bkioshn May 5, 2024
051715a
chore: fix spelling
bkioshn May 5, 2024
aec6a22
feat(rust): Add parallel building of Tooling and Rust code (#240)
stevenj May 6, 2024
3c83ff4
doc: update rust doc
bkioshn May 6, 2024
af861b6
fix: update project dic
bkioshn May 6, 2024
54a0251
fix(rust): Fix/improve rust builder (#243)
stevenj May 10, 2024
03d1d05
fix(rust): Remove debug code in Earthfile
stevenj May 13, 2024
8744282
fix(cspell): Remove redundant word from dictionary
stevenj May 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .config/dictionaries/project.dic
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
aarch
bindgen
buildkit
camelcase
codegen
colordiff
cowsay
cytopia
depgraph
devenv
dind
dockerhub
Expand Down Expand Up @@ -70,7 +72,9 @@ rustdoc
rustdocflags
rustflags
rustfmt
rustup
sqlfluff
stdcfgs
subproject
subprojects
superfences
Expand All @@ -80,11 +84,13 @@ testdocs
testpackage
testunit
Timoni
toolsets
transpiling
UDCs
uniseg
voteplan
wasi
wasmtime
webkitallowfullscreen
WORKDIR
xerrors
Expand Down
15 changes: 10 additions & 5 deletions Earthfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
VERSION 0.8

IMPORT ./earthly/mdlint AS mdlint-ci
IMPORT ./earthly/cspell AS cspell-ci
IMPORT ./earthly/bash AS bash-ci
IMPORT ./earthly/spectral AS spectral-ci

# cspell: words livedocs sitedocs


Expand All @@ -11,17 +16,17 @@ check-markdown:
markdown-check-fix:
LOCALLY

DO ./earthly/mdlint+MDLINT_LOCALLY --src=$(echo ${PWD}) --fix=--fix
DO mdlint-ci+MDLINT_LOCALLY --src=$(echo ${PWD}) --fix=--fix

# check-spelling Check spelling in this repo inside a container.
check-spelling:
DO ./earthly/cspell+CHECK
DO cspell-ci+CHECK

# check-bash - test all bash files lint properly according to shellcheck.
check-bash:
FROM alpine:3.19

DO ./earthly/bash+SHELLCHECK --src=.
DO bash-ci+SHELLCHECK --src=.

# Internal: Reference to our repo root documentation used by docs builder.
repo-docs:
Expand Down Expand Up @@ -50,5 +55,5 @@ edit-docs:

# check-lint-openapi - OpenAPI linting from a given directory
check-lint-openapi:
FROM ./earthly/spectral+spectral-base
DO ./earthly/spectral+BUILD_SPECTRAL --dir="./examples/openapi" --file_type="json"
FROM spectral-ci+spectral-base
DO spectral-ci+BUILD_SPECTRAL --dir="./examples/openapi" --file_type="json"
8 changes: 5 additions & 3 deletions cli/Earthfile
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
VERSION 0.8

IMPORT ../earthly/go AS go-ci

FROM golang:1.21-alpine3.19

# cspell: words onsi ldflags extldflags

fmt:
DO ../earthly/go+FMT --src="go.mod go.sum cmd pkg"
DO go-ci+FMT --src="go.mod go.sum cmd pkg"

lint:
DO ../earthly/go+LINT --src="go.mod go.sum cmd pkg"
DO go-ci+LINT --src="go.mod go.sum cmd pkg"

deps:
WORKDIR /work
CACHE --persist --sharing shared /go

RUN apk add --no-cache gcc musl-dev
DO ../earthly/go+DEPS
DO go-ci+DEPS

src:
FROM +deps
Expand Down
14 changes: 9 additions & 5 deletions docs/Earthfile
Original file line number Diff line number Diff line change
@@ -1,27 +1,31 @@
VERSION 0.8

IMPORT ../earthly/docs AS docs-ci
IMPORT .. AS cat-ci
IMPORT ../examples/postgresql AS postgresql-ci

# Copy all the source we need to build the docs
src:
# Common src setup
DO ../earthly/docs+SRC
DO docs-ci+SRC

# Now copy into that any artifacts we pull from the builds.
COPY --dir ../+repo-docs/repo includes
COPY --dir cat-ci+repo-docs/repo includes

# Copy docs we build in the postgres example.
COPY --dir ../examples/postgresql+build/docs src/appendix/examples/built_docs/postgresql
COPY --dir postgresql-ci+build/docs src/appendix/examples/built_docs/postgresql

# Build the docs here.
docs:
FROM +src

DO ../earthly/docs+BUILD
DO docs-ci+BUILD


# Make a docker image that can serve the docs for development purposes.
# This target is only for local developer use.
local:
DO ../earthly/docs+PACKAGE
DO docs-ci+PACKAGE

COPY +docs/ /usr/share/nginx/html

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ We will not use the `rust-version` feature of `cargo.toml` during initial bring
We have not defined a maximum range of valid Rust versions, and always build ONLY with the version defined in `rust-toolchain.toml`.

Currently the ONLY supported rust version is the one specified by `rust-toolchain.toml`.
However `rust-toolchain.toml` breaks CI when it is used, so this file is ONLY used for local development and MUST
be synchronized with the toolchain version used in CI.

If at a later time, a range of rust versions is decided to be supported then:

Expand Down
136 changes: 93 additions & 43 deletions docs/src/guides/languages/rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ tags:
# :simple-rust: Rust
<!-- markdownlint-enable single-h1 -->

<!-- cspell: words toolsets stdcfgs depgraph -->

## Introduction

<!-- markdownlint-disable max-one-sentence-per-line -->
Expand Down Expand Up @@ -49,31 +47,40 @@ Also we will take a look how we are setup Rust projects and what configuration i
### Prepare base builder

```Earthfile
VERSION --try 0.8
VERSION 0.8

IMPORT ./../../earthly/rust AS rust-ci

# Set up our target toolchains, and copy our files.
builder:
DO ./../../earthly/rust+SETUP
DO rust-ci+SETUP

COPY --dir .cargo .config crates .
COPY Cargo.toml .
COPY clippy.toml deny.toml rustfmt.toml .
```

The first target `builder` is responsible for preparing an already configured Rust environment,
instal all needed tools and dependencies.
The first target `builder` is responsible for preparing configured Rust environments and,
install all needed tools and dependencies.

The fist step of the `builder` target is to prepare a Rust environment via `+rust-base` target.
Next step is to copy source code of the project.
#### Builder steps

1. First step of `+builder` target is to prepare a Rust environment via `+installer` target,
which is called in `+SETUP` FUNCTION.
The `+installer` target installs necessary tools for `+rust-base` target and copies
common scripts and standardized Rust configs.
The `+rust-base` provides a base Rustup build environment.
It installs necessary packages, including development libraries and tools.
Clippy linter, LLVM tools for generating code coverage, and nightly toolchain are installed.
2. Next step is to copy source code of the project.
Note that you need to copy only needed files for Rust build process,
any other irrelevant stuff should omitted.
And finally finalize the build with `+SETUP` Function.
The `+SETUP` Function requires `rust-toolchain.toml` file,
with the specified `channel` option in it.
This `rust-toolchain.toml` file could be specified
via the `toolchain` argument of the `+SETUP` target like this
with defining the specific location of this file with the specific name.
By default `toolchain` setup to `rust-toolchain.toml`.
3. And finally finalize the build with `+SETUP` FUNCTION which takes no arguments.

<!-- markdownlint-disable max-one-sentence-per-line -->
!!! Warning
Please ensure that Rust version set in `rust-toolchain.toml` matches the Docker image tag uses in `+rust-base` target.
<!-- markdownlint-enable max-one-sentence-per-line -->

### Running checks

Expand All @@ -83,7 +90,7 @@ By default `toolchain` setup to `rust-toolchain.toml`.
check:
FROM +builder

RUN /scripts/std_checks.py
DO rust-ci+EXECUTE --cmd="/scripts/std_checks.py"

# Test which runs check with all supported host tooling. Needs qemu or rosetta to run.
# Only used to validate tooling is working across host toolsets.
Expand All @@ -92,8 +99,8 @@ all-hosts-check:
```

With prepared environment and all data, we're now ready to start operating with the source code and configuration files.
The `check` target which actually performs all checks and validation
with the help of `std_checks.py` script.
The `+check` target performs all checks and validation procedures
using the help of `std_checks.py` script.
This script performs static checks of the Rust project as
`cargo fmt`, `cargo machete`, `cargo deny` which will validate formatting,
find unused dependencies and any supply chain issues with dependencies.
Expand All @@ -105,18 +112,18 @@ look at `./earthly/rust/stdcfgs/cargo_config.toml`)Checking Rust Code Format.
3. `cargo machete` - Checking for Unused Dependencies.
4. `cargo deny check` - Checking for Supply Chain Issues.

As it was mentioned above it validates configuration files as
As it was mentioned above, it validates configuration files as
`.cargo/config.toml`, `rustfmt.toml`, `.config/nextest.toml`, `clippy.toml`, `deny.toml`
to be the same as defined in `earthly/rust/stdcfgs` directory of the `catalyst-ci` repo.
So when you are going to setup a new Rust project copy these configuration files
So when you are going to setup a new Rust project, copy these configuration files
described above to the appropriate location of your Rust project.

Another target as `all-hosts-check` just invokes `check` with the specified `--platform`.
It is needed for the local development to double check that everything is works for different platforms.
It is important to define a `linux` target platform with a proper cpu architecture
Another target as `+all-hosts-check` just invokes `+check` with the specified `--platform`.
It is needed for the local development to double check that everything works for different platforms.
It is important to define a `linux` target platform with a proper CPU architecture
for the Rust project when you are building it inside Docker
and check the build process with different scenarios.
The same approach we will see for the another targets of this guide.
The same approach will be seen in other targets throughout this guide.

### Build

Expand All @@ -126,37 +133,32 @@ The same approach we will see for the another targets of this guide.
build:
FROM +builder

TRY
RUN /scripts/std_build.py --cov_report="coverage-report.info" \
--with_docs \
--libs="bar" \
--bins="foo/foo"
FINALLY
SAVE ARTIFACT target/nextest/ci/junit.xml example.junit-report.xml AS LOCAL
SAVE ARTIFACT coverage-report.info example.coverage-report.info AS LOCAL
END

SAVE ARTIFACT target/doc doc
SAVE ARTIFACT target/release/foo foo
# This WILL save the junit and coverage reports even if it fails.
DO rust-ci+EXECUTE \
--cmd="/scripts/std_build.py --cov_report=$HOME/coverage-report.info --libs=bar --bins=foo/foo" \
--junit="example.junit-report.xml" \
--coverage="example.coverage-report.info" \
--output="release/[^\./]+" \
--docs="true"

DO ./../../earthly/rust+SMOKE_TEST --bin="foo"
SAVE ARTIFACT target/release/foo foo

# Test which runs check with all supported host tooling. Needs qemu or rosetta to run.
# Only used to validate tooling is working across host toolsets.
all-hosts-build:
BUILD --platform=linux/amd64 --platform=linux/arm64 +build
```

After successful performing checks of the Rust project we can finally `build` artifacts.
Obviously it inherits `builder` target environment and than performs build of the binary.
After successful performing checks of the Rust project we can finally build artifacts.
Obviously it inherits `+builder` target environment and then performs build of the binary.
Important to note that in this particular example we are dealing with the executable Rust project,
so it produces binary as a final artifact.
Another case of the building Rust library we will consider later.
We will discuss another scenario of building a Rust library later.
Actual build process is done with the `std_build.py` script.
Here is the full list of configuration of this script:

```bash
usage: std_build.py [-h] [--build_flags BUILD_FLAGS]
usage: std_build.py [-h] [-v] [--build_flags BUILD_FLAGS]
[--doctest_flags DOCTEST_FLAGS] [--test_flags TEST_FLAGS]
[--bench_flags BENCH_FLAGS] [--with_test]
[--cov_report COV_REPORT] [--with_bench] [--libs LIBS]
Expand All @@ -165,7 +167,8 @@ Here is the full list of configuration of this script:
Rust build processing.

options:
-h, --help show this help message and exit
-h, --help Show this help message and exit.
-v --verbose Show the output of executed commands verbosely.
--build_flags BUILD_FLAGS
Additional command-line flags that can be passed to
the `cargo build` command.
Expand Down Expand Up @@ -226,11 +229,12 @@ for the specified `--libs="crate1"` argument.
10. Running smoke tests on provided binary names (`--bins` argument).

Final step is to provide desired artifacts: docs and binary.
Note that all commands within the `std_build.py` are written to be run in parallel, resulting in a faster speeds.

### Test

As you already mentioned that running of unit tests is done during the `build` process,
but if you need some integration tests pls follow how it is done for [PostgreSQL builder](./postgresql.md),
but if you need some integration tests please follow this [PostgreSQL builder](./postgresql.md),
Rust will have the same approach.

### Release and publish
Expand All @@ -248,6 +252,52 @@ Unfortunately, Rust tooling does not have the capability to preserve and maintai
`stable` and `nightly` toolchains simultaneously.
In our builds, we only preserve the `stable` toolchain version (`rust-toolchain.toml` file).

## Rust tools

All the necessary Rust tools can be found in [tool](../../../../earthly/rust/tools/Earthfile).

## Rust FUNCTIONs

While leveraging the [Earthly lib/rust](https://github.com/earthly/lib/tree/main/rust),
the following Rust FUNCTIONs are customize to align with our specific requirements
that our project needed.

* `EXECUTE` : This FUNCTION, adapted from the [Earthly lib/rust](https://github.com/earthly/lib/tree/main/rust),
is tailored to execute commands according to user specifications.
It serves a pivotal role in managing Rust project builds, handling outputs, and supporting features
such as `JUnit` reporting and code coverage.
Our modifications ensure that the command
executed utilize the cache efficiently, which result in a faster compilation time.

```Earthfile
# Example of using `EXECUTE` with a simple copy command
DO +EXECUTE --cmd="cp $CARGO_INSTALL_ROOT/config.toml $CARGO_HOME/config.toml"
```

* `CARGO` : This FUNCTION serves as a shim of the original lib/rust `CARGO` FUNCTION
to guarantee consistent usage of the appropriate upstream Rust library.
Therefore, users of `catalyst-ci` who wish to use `rust+CARGO` from `lib/rust`
should utilize the `+CARGO` implementation provided in this repository.

```Earthfile
# Example of using `CARGO` to install a Rust tool
DO rust-ci+CARGO --args="install cargo-nextest --version=0.9.70 --locked"
```

* `COPY_OUTPUT` : This FUNCTION serves as a shim of the original lib/rust `COPY_OUTPUT`
to facilitate the SAVE of ARTIFACT from the target folder (mounted cache) into the image layer.
This FUNCTION will always trying to minimize the total size of the copied files,
which result in a faster copy.

```Earthfile
# Example of using `COPY_OUTPUT` where `SAVE ARTIFACT` is used
# The `COPY_OUTPUT` will copy the output to `target` folder
DO rust+COPY_OUTPUT --output="nextest/ci/junit.xml"
SAVE ARTIFACT target/nextest/ci/junit.xml AS LOCAL "$junit"
```

**Note that in order to called the above FUNCTIONs, `rust+INIT` should be called first.**

## Conclusion

You can see the final `Earthfile` [here](https://github.com/input-output-hk/catalyst-ci/blob/master/examples/rust/Earthfile)
Expand Down
Loading
Loading