# The name of your workflow. GitHub displays the names of your workflows on your repository's "Actions" tab name: Rust # To automatically trigger the workflow on: # NB: this differs from the book's project! # These settings allow us to run this specific CI pipeline for PRs against # this specific branch (a.k.a. book chapter). push: branches: - main pull_request: types: [opened, synchronize, reopened] branches: - main env: CARGO_TERM_COLOR: always SQLX_VERSION: 0.8.6 SQLX_FEATURES: "rustls,postgres" APP_USER: app APP_USER_PWD: secret APP_DB_NAME: newsletter # A workflow run is made up of one or more jobs, which run in parallel by default # Each job runs in a runner environment specified by runs-on jobs: # Unique identifier of our job (`job_id`) test: # Sets the name `Test` for the job, which is displayed in the GitHub UI name: Test # Containers must run in Linux based operating systems runs-on: ubuntu-latest # Service containers to run alongside the `test` container job services: # Label used to access the service container postgres: # Docker Hub image image: postgres # Environment variables scoped only for the `postgres` element env: POSTGRES_USER: postgres POSTGRES_PASSWORD: password POSTGRES_DB: postgres # When you map ports using the ports keyword, GitHub uses the --publish command to publish the container’s ports to the Docker host # Opens tcp port 5432 on the host and service container ports: - 5432:5432 steps: # Downloads a copy of the code in your repository before running CI tests - name: Check out repository code # The uses keyword specifies that this step will run v4 of the actions/checkout action. # This is an action that checks out your repository onto the runner, allowing you to run scripts or other actions against your code (such as build and test tools). # You should use the checkout action any time your workflow will run against the repository's code. uses: actions/checkout@v4 # This GitHub Action installs a Rust toolchain using rustup. It is designed for one-line concise usage and good defaults. # It also takes care of caching intermediate build artifacts. - name: Install the Rust toolchain uses: actions-rust-lang/setup-rust-toolchain@v1 - name: Install sqlx-cli run: cargo install sqlx-cli --version=${{ env.SQLX_VERSION }} --features ${{ env.SQLX_FEATURES }} --no-default-features --locked - name: Create app user in Postgres run: | sudo apt-get install postgresql-client # Create the application user CREATE_QUERY="CREATE USER ${APP_USER} WITH PASSWORD '${APP_USER_PWD}';" PGPASSWORD="password" psql -U "postgres" -h "localhost" -c "${CREATE_QUERY}" # Grant create db privileges to the app user GRANT_QUERY="ALTER USER ${APP_USER} CREATEDB;" PGPASSWORD="password" psql -U "postgres" -h "localhost" -c "${GRANT_QUERY}" - name: Migrate database run: SKIP_DOCKER=true ./scripts/init_db.sh - name: Run tests run: cargo test - name: Check that queries are fresh run: cargo sqlx prepare --check --workspace # `fmt` container job fmt: name: Rustfmt runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install the Rust toolchain uses: actions-rust-lang/setup-rust-toolchain@v1 with: components: rustfmt - name: Enforce formatting run: cargo fmt --check # `clippy` container job clippy: name: Clippy runs-on: ubuntu-latest env: # This environment variable forces sqlx to use its offline mode, # which means that it will not attempt to connect to a database # when running the tests. It'll instead use the cached query results. # We check that the cached query results are up-to-date in another job, # to speed up the overall CI pipeline. # This will all be covered in detail in chapter 5. SQLX_OFFLINE: true steps: - uses: actions/checkout@v4 - name: Install the Rust toolchain uses: actions-rust-lang/setup-rust-toolchain@v1 with: components: clippy - name: Linting run: cargo clippy -- -D warnings # `coverage` container job coverage: name: Code coverage runs-on: ubuntu-latest services: postgres: image: postgres env: POSTGRES_USER: postgres POSTGRES_PASSWORD: password POSTGRES_DB: postgres ports: - 5432:5432 steps: - uses: actions/checkout@v4 - name: Install the Rust toolchain uses: actions-rust-lang/setup-rust-toolchain@v1 with: components: llvm-tools-preview - name: Install sqlx-cli run: cargo install sqlx-cli --version=${{ env.SQLX_VERSION }} --features ${{ env.SQLX_FEATURES }} --no-default-features --locked - name: Create app user in Postgres run: | sudo apt-get install postgresql-client # Create the application user CREATE_QUERY="CREATE USER ${APP_USER} WITH PASSWORD '${APP_USER_PWD}';" PGPASSWORD="password" psql -U "postgres" -h "localhost" -c "${CREATE_QUERY}" # Grant create db privileges to the app user GRANT_QUERY="ALTER USER ${APP_USER} CREATEDB;" PGPASSWORD="password" psql -U "postgres" -h "localhost" -c "${GRANT_QUERY}" - name: Migrate database run: SKIP_DOCKER=true ./scripts/init_db.sh - name: Install cargo-llvm-cov uses: taiki-e/install-action@cargo-llvm-cov - name: Generate code coverage run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info - name: Generate report run: cargo llvm-cov report --html --output-dir coverage - uses: actions/upload-artifact@v4 with: name: "Coverage report" path: coverage/