LukeMathWalker / zero-to-production

Code for "Zero To Production In Rust", a book on API development using Rust.
https://www.zero2prod.com
Apache License 2.0
5.48k stars 475 forks source link

[3.8.5.5 Updating Our CI Pipeline]: Add .gitlab.yml file #166

Open ghost opened 1 year ago

ghost commented 1 year ago

In chapter 3.8.5.* we have broked the current test stage in our CI pipeline. Need to provide the configuration for the gitlab users as well as github users

dsbahr commented 9 months ago

I'm not a Gitlab expert, but I managed to get a working pipeline with this gitlab-ci.yml file:

image: "rust:latest"

# Runs the pipeline on both the main branch and all feature branches
workflow:
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
    - if: '$CI_COMMIT_BRANCH =~ /^feature\//'

services:
  - postgres:latest

variables:
  POSTGRES_DB: newsletter
  POSTGRES_USER: postgres
  POSTGRES_PASSWORD: password
  POSTGRES_HOST: postgres
  DB_PORT: 5432
  DATABASE_URL: "postgres://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST:$DB_PORT/$POSTGRES_DB"
  Z2P__DATABASE__HOST: $POSTGRES_HOST

cache: # Caches build artifacts so we don't build from scratch in both build and test
  key: ${CI_COMMIT_REF_SLUG}
  paths:
    - .cargo/bin
    - .cargo/registry/index
    - .cargo/registry/cache
    - target/debug/deps
    - target/debug/build
  policy: pull-push

default:
  before_script:
    - export CARGO_HOME="$CI_PROJECT_DIR/.cargo"
    - export PATH="$CARGO_HOME/bin:$PATH"
    - rustc --version
    - cargo --version
    - if ! [ -x "$(command -v cargo-sqlx)" ]; then - cargo install --version='~0.7' sqlx-cli --no-default-features --features rustls,postgres; fi
    - apt-get update -yq && apt-get install -yq postgresql-client
    - SKIP_DOCKER=true ./scripts/init_db.sh
    # This is to ensure that the database is reachable and give it some time to initialize.
    - until psql "dbname=$POSTGRES_DB user=$POSTGRES_USER password=$POSTGRES_PASSWORD host=postgres" -c '\l'; do sleep 3; done

stages:
  - build
  - test

build:
  stage: build
  script:
    - cargo build

test-code:
  stage: test
  script:
    - cargo test
    - if ! [ -x "$(command -v cargo-tarpaulin)" ]; then cargo install cargo-tarpaulin; fi
    - cargo tarpaulin --ignore-tests

lint-code:
  stage: test
  script:
    - rustup component add clippy
    - cargo clippy -- -D warnings

audit-code:
  stage: test
  script:
    - if ! [ -x "$(command -v cargo-audit)" ]; then cargo install cargo-audit; fi
    - cargo audit

and this change to configuration.rs:


#[derive(serde::Deserialize)]
pub struct  Settings {
    pub database: DatabaseSettings,
    pub application_port: u16
}

#[derive(serde::Deserialize)]
pub struct DatabaseSettings {
    pub username: String,
    pub password: String,
    pub port: u16,
    pub host: String,
    pub database_name: String
}

impl DatabaseSettings {
    pub fn connection_string(&self) -> String {
        format!(
            "postgres://{}:{}@{}:{}/{}",
            self.username, self.password, self.host, self.port, self.database_name
        )
    }
}

pub fn get_configuration() -> Result<Settings, config::ConfigError>{
    // Initialize our configuration reader
    let settings = config::Config::builder()
        // Read configuration values from configuration.yaml file
        .add_source(
            config::File::new("configuration.yaml", config::FileFormat::Yaml)
        )
        .add_source(
            config::Environment::with_prefix("Z2P").separator("__")
        )
        .build()?;

    // Try to convert configuration values into Settings type
    settings.try_deserialize::<Settings>()
}

I've added Environment Variables as another config source, with a prefix of Z2P so I could override the database host from 127.0.0.1 to postgres which seemed necessary in order to connect to Postgres runtime in the health_check.rs integration test.

Now I get the same RowNotFound error in my pipeline as when running locally.

Maybe it's helpful for someone else trying to get gitlab working :)