diff --git a/.github/workflows/rust-example.yaml b/.github/workflows/rust-example-app.yaml similarity index 56% rename from .github/workflows/rust-example.yaml rename to .github/workflows/rust-example-app.yaml index aea6d8c..379545b 100644 --- a/.github/workflows/rust-example.yaml +++ b/.github/workflows/rust-example-app.yaml @@ -1,4 +1,4 @@ -name: Rust & Cargo Build and Deploy +name: Rust & Cargo Quotes Application on: workflow_dispatch env: @@ -7,6 +7,14 @@ env: CARGO_REGISTRIES_INNERSOURCE_TOKEN: ${{ secrets.RUST_EXAMPLE_AUTHENTICATION_TOKEN }} CARGO_REGISTRIES_JFROGQUOTES_TOKEN: ${{ secrets.RUST_EXAMPLE_AUTHENTICATION_TOKEN }} +# The default working-directory is needed, due to all example Actions specs residing in the same directory, but each +# package example code is in different directories. This `default` config saves us the effort of setting a +# `working-directory` on each step. +defaults: + run: + shell: bash + working-directory: ./rust/jfrog_app + jobs: build-and-publish: runs-on: ubuntu-latest @@ -16,18 +24,13 @@ jobs: - name: Validate Cargo installation run: cargo --version - - name: Build Library - working-directory: ./rust/jfrog_quotes - run: cargo build --release --verbose - - - name: Publish Library To Artifactory - working-directory: ./rust/jfrog_quotes - run: cargo publish --token "Bearer ${{ secrets.RUST_EXAMPLE_AUTHENTICATION_TOKEN }}" + - name: Preprocess Cargo.toml + run: | + base_url=${{ vars.RUST_EXAMPLE_CARGO_BASE_URL }} + sed -i "s/^version = \"0.1.dev\"/version = \"0.1.${base_url}\"/" config.toml - name: Build Application - working-directory: ./rust/jfrog_app run: cargo build --release --verbose - name: Publish Application To Artifactory - working-directory: ./rust/jfrog_app run: cargo publish --token "Bearer ${{ secrets.RUST_EXAMPLE_AUTHENTICATION_TOKEN }}" \ No newline at end of file diff --git a/.github/workflows/rust-example-library.yaml b/.github/workflows/rust-example-library.yaml new file mode 100644 index 0000000..48f9e91 --- /dev/null +++ b/.github/workflows/rust-example-library.yaml @@ -0,0 +1,38 @@ +name: Rust & Cargo Innersource Library +on: workflow_dispatch + +env: + CARGO_TERM_COLOR: always + CARGO_REGISTRIES_CRATES_TOKEN: ${{ secrets.RUST_EXAMPLE_AUTHENTICATION_TOKEN }} + CARGO_REGISTRIES_INNERSOURCE_TOKEN: ${{ secrets.RUST_EXAMPLE_AUTHENTICATION_TOKEN }} + CARGO_REGISTRIES_JFROGQUOTES_TOKEN: ${{ secrets.RUST_EXAMPLE_AUTHENTICATION_TOKEN }} + +# The default working-directory is needed, due to all example Actions specs residing in the same directory, but each +# package example code is in different directories. This `default` config saves us the effort of setting a +# `working-directory` on each step. +defaults: + run: + shell: bash + working-directory: ./rust/jfrog_quotes + +jobs: + build-and-publish: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Validate Cargo installation + run: cargo --version + + # This step is helpful to prevent messing with different library binary checksums being produced on the same semantic version + # Cargo doesn't accommodate dynamic values to be passed in to Cargo.toml, so we have to use `sed` instead. + - name: Preprocess Cargo.toml + run: | + build_number=${{ github.run_number }} + sed -i "s/^version = \"0.1.dev\"/version = \"0.1.${build_number}\"/" Cargo.toml + + - name: Build Library + run: cargo build --release --verbose + + - name: Publish Library To Artifactory + run: cargo publish --allow-dirty --token "Bearer ${{ secrets.RUST_EXAMPLE_AUTHENTICATION_TOKEN }}" \ No newline at end of file diff --git a/rust/README.md b/rust/README.md index c847af0..7de52c3 100644 --- a/rust/README.md +++ b/rust/README.md @@ -1,26 +1,52 @@ # Rust and Cargo with Integration With Artifactory # Cargo Package Manager Integration with Artifactory -A repo to demonstrate Rust's package manager, Cargo, and how it integrates with Artifactory. +This is a small repo to demonstrate Rust's package manager, Cargo, and how it integrates with Artifactory. # Project Goal The two Rust projects in this folder will demonstrate the basics of integrating Rust's package manager, Cargo, with Jfrog's Artifactory. # Project Structure -This repo will hold two projects: an [Inner Source](https://en.wikipedia.org/wiki/Inner_source) library, to be built and published with Artifactory's Cargo -integration, and a "Production" application that will incorporate the library. +This repo will hold two projects: an [Inner Source](https://en.wikipedia.org/wiki/Inner_source) library, to be built and published with Artifactory's Cargo integration, and a "Production" application that will incorporate the library. ## Inner Source Library -A simple library that will return a randomly-selected quote about JFrog, The Secure Software Supply Chain experts. +This is a simple library that will return a randomly-selected quote about JFrog, The Secure Software Supply Chain +experts. ## Production Application -A basic Rust application that will incorporate the Inner Source library. +A basic Rust application that will incorporate the Inner Source library. Upon execution, it will print out a +randomly selected quote to the console. ## Pre Reqs (Local Build) 1. Install Cargo 2. Configure Cargo -3. Setup `~/.cargo/credentials`. Note, if you use a credentials file, DO NOT check this into Version Control +3. Create three repositories in an instance of Artifactory: One remote repository that proxies `crates.io`, one + local repository to host the "innersource" library and one local repository to host the actual application binary. +4. Using these repositories edit the two Cargo config files as follows: +`jfrog_app/.cargo/config.toml`: This file will take the "innersource" library local repo and +```toml +[registry] +default = "jfrogquotes" + +[registries.jfrogquotes] +index = "sparse+https://tomjfrog.jfrog.io/artifactory/api/cargo/jfrogquotes-cargo-local/index/" + +[registries.innersource] +index = "sparse+https://tomjfrog.jfrog.io/artifactory/api/cargo/innersource-cargo-local/index/" +``` +`jfrog_quotes/.cargo/config.toml` +```toml +[registry] +default = "innersource" + +[registries.innersource] +index = "sparse+https://BASE_URL/artifactory/api/cargo/innersource-cargo-local/index/" + +[registries.crates-remote] +index = "sparse+https://BASE_URL/artifactory/api/cargo/crates-remote/index/" +``` +5. Setup `~/.cargo/credentials`. Note, if you use a credentials file, DO NOT check this into Version Control ```toml [registries.artifactory] token = "Bearer " @@ -37,7 +63,16 @@ export CARGO_REGISTRIES_FOO_TOKEN="Bearer bar" ## Cargo configuration TODO: Provide details on the library's `Cargo.toml`, esp around where to resolve external dependencies ## Steps to build and publish the innersource library, `jfrog_quotes` + ### Build the Library +To build the library, first run a local build. Enter the root of the `rust` example and execute `cargo build +--release`. + +> Note: The first time this is run, a file called `Cargo.lock` will be generated. It's important to commit this +> to version control. The version of the library in the remote Cargo remote, hosted in Artifactory, will be pinned +> to a specific SHA associated with the version. By checking in the Cargo.lock, it will ensure that the correct SHA +> will always be used. + ```bash cd rust/jfrog_quotes cargo build --release @@ -47,3 +82,11 @@ cargo build --release cargo publish --registry innersource ``` +## Advanced Use-Case: Execute build and deploy in Github Actions +Github Actions, one of the most popular CI tools on the market today, has native support for Cargo in it's hosted +runners. The example here has two Github Actions specs: building the library and building the application. Follow +these steps to get this use-case implemented. + +### Add Repository Variable for JFrog URL + + diff --git a/rust/jfrog_app/Cargo.toml b/rust/jfrog_app/Cargo.toml index 33fc26b..ab99779 100644 --- a/rust/jfrog_app/Cargo.toml +++ b/rust/jfrog_app/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "jfrog_app" -version = "0.1.0" +version = "0.1.dev" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -jfrog_quotes = { version = "0.1.0", registry = "innersource" } +jfrog_quotes = { version = "0.1.7", registry = "innersource" } diff --git a/rust/jfrog_quotes/.cargo/config.toml b/rust/jfrog_quotes/.cargo/config.toml index db4dfe3..5e19a2a 100644 --- a/rust/jfrog_quotes/.cargo/config.toml +++ b/rust/jfrog_quotes/.cargo/config.toml @@ -3,7 +3,7 @@ default = "innersource" [registries.innersource] -index = "sparse+https://tomjfrog.jfrog.io/artifactory/api/cargo/innersource-cargo-local/index/" +index = "sparse+https://BASE_URL/artifactory/api/cargo/innersource-cargo-local/index/" [registries.crates-remote] -index = "sparse+https://tomjfrog.jfrog.io/artifactory/api/cargo/crates-remote/index/" +index = "sparse+https://BASE_URL/artifactory/api/cargo/crates-remote/index/" diff --git a/rust/jfrog_quotes/Cargo.toml b/rust/jfrog_quotes/Cargo.toml index 17dafa1..9154356 100644 --- a/rust/jfrog_quotes/Cargo.toml +++ b/rust/jfrog_quotes/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "jfrog_quotes" -version = "0.1.0" +version = "0.1.dev" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html