diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml new file mode 100644 index 0000000..1609da3 --- /dev/null +++ b/.github/workflows/integration-tests.yml @@ -0,0 +1,55 @@ +name: Integration Tests + +on: + workflow_dispatch: + push: + branches: ["main"] + pull_request_target: + types: [opened, synchronize, reopened, ready_for_review, labeled] + +env: + CARGO_TERM_COLOR: always + +jobs: + integration-tests: + runs-on: ubuntu-latest + + # Run if: + # 1. Manual trigger or push to main, OR + # 2. PR from trusted author (COLLABORATOR), OR + # 3. PR from untrusted author with "safe to test" label + if: | + github.event_name != 'pull_request_target' || + github.event.pull_request.author_association == 'COLLABORATOR' || + contains(github.event.pull_request.labels.*.name, 'safe-to-test') + + permissions: + id-token: write + contents: read + + steps: + - name: Checkout + uses: actions/checkout@v5 + with: + ref: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.sha || github.sha }} + + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v5 + with: + role-to-assume: ${{ secrets.ROLE_ARN }} + role-session-name: secrets-manager-agent-ci-${{ github.run_id }} + aws-region: us-east-1 + + - name: Build agent binary + run: cargo build + + - name: Run integration tests + run: | + cd integration-tests + cargo test -- --test-threads=1 diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 48e5171..6dd6d1d 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -48,9 +48,9 @@ jobs: - name: Build run: cargo build --verbose - name: Run tests - run: cargo test --verbose --all-features --no-fail-fast + run: cargo test --verbose --all-features --no-fail-fast --workspace --exclude integration-tests - name: Code Coverage - run: cargo llvm-cov --all-features --workspace --codecov --output-path ./codecov.json + run: cargo llvm-cov --all-features --workspace --exclude integration-tests --codecov --output-path ./codecov.json - name: Publish Code Coverage uses: codecov/codecov-action@v5 with: diff --git a/integration-tests/tests/common.rs b/integration-tests/tests/common.rs index 4e3d78a..e531c20 100644 --- a/integration-tests/tests/common.rs +++ b/integration-tests/tests/common.rs @@ -192,13 +192,12 @@ impl TestSecrets { } pub async fn setup() -> Self { - let test_prefix = format!( - "aws-sm-agent-test-{}", - std::time::SystemTime::now() - .duration_since(std::time::UNIX_EPOCH) - .unwrap() - .as_secs() - ); + let timestamp = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_nanos(); + + let test_prefix = format!("aws-sm-agent-test-{}", timestamp); let config = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await; let client = aws_sdk_secretsmanager::Client::new(&config); diff --git a/integration-tests/tests/secret_retrieval.rs b/integration-tests/tests/secret_retrieval.rs index 89b62af..4758aaf 100644 --- a/integration-tests/tests/secret_retrieval.rs +++ b/integration-tests/tests/secret_retrieval.rs @@ -3,7 +3,6 @@ mod common; use common::*; #[tokio::test] -#[ignore = "integration test - requires AWS credentials"] async fn test_secret_retrieval_by_name() { let secrets = TestSecrets::setup().await; let secret_name = secrets.secret_name(SecretType::Basic); @@ -23,7 +22,6 @@ async fn test_secret_retrieval_by_name() { } #[tokio::test] -#[ignore = "integration test - requires AWS credentials"] async fn test_secret_retrieval_by_arn() { let secrets = TestSecrets::setup().await; let secret_name = secrets.secret_name(SecretType::Basic); @@ -52,7 +50,6 @@ async fn test_secret_retrieval_by_arn() { } #[tokio::test] -#[ignore = "integration test - requires AWS credentials"] async fn test_binary_secret_retrieval() { let secrets = TestSecrets::setup().await; let secret_name = secrets.secret_name(SecretType::Binary); @@ -72,7 +69,6 @@ async fn test_binary_secret_retrieval() { } #[tokio::test] -#[ignore = "integration test - requires AWS credentials"] async fn test_version_stage_retrieval() { let secrets = TestSecrets::setup().await; let secret_name = secrets.secret_name(SecretType::Versioned); @@ -124,7 +120,6 @@ async fn test_version_stage_retrieval() { } #[tokio::test] -#[ignore = "integration test - requires AWS credentials"] async fn test_version_id_retrieval() { let secrets = TestSecrets::setup().await; let secret_name = secrets.secret_name(SecretType::Versioned); @@ -174,7 +169,6 @@ async fn test_version_id_retrieval() { } #[tokio::test] -#[ignore = "integration test - requires AWS credentials"] async fn test_large_secret_retrieval() { let secrets = TestSecrets::setup().await; let secret_name = secrets.secret_name(SecretType::Large); diff --git a/test-local.sh b/test-local.sh index 0feb85d..1973c2b 100755 --- a/test-local.sh +++ b/test-local.sh @@ -15,9 +15,9 @@ cargo build echo "Running integration tests..." cd integration-tests -# Run integration tests (including ignored ones) -# Tests now handle their own setup and cleanup -cargo test -- --test-threads=1 --ignored +# Run integration tests sequentially (matches CI behavior) +# Tests handle their own setup and cleanup +cargo test -- --test-threads=1 cd ..