Skip to content

Commit 4ca2f46

Browse files
committed
ci: add dotnet-ci workflow and Terraform config for GitHub environment
- Add .github/workflows/dotnet-ci.yml: unit-test job runs on every PR/push with no env vars (integration tests auto-skip); integration-test job is gated by vars.INTEGRATION_TESTS_ENABLED and uses the integration-tests GitHub environment provisioned by Terraform. - Add terraform/ config backfilling the existing repo, team access, and branch ruleset; creates the integration-tests environment with SECRET_SERVER_* secrets and INTEGRATION_TESTS_ENABLED repo variable. - State stored in Azure Blob (kfghtfstatesn84ro / tfstate container).
1 parent d4a3187 commit 4ca2f46

10 files changed

Lines changed: 315 additions & 0 deletions

File tree

.github/workflows/dotnet-ci.yml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: Build and Test
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- main
8+
- release-*
9+
10+
jobs:
11+
unit-test:
12+
name: Build and Unit Test
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- uses: actions/setup-dotnet@v4
18+
with:
19+
dotnet-version: '10.x'
20+
21+
- name: Build
22+
run: dotnet build delinea-secretserver-pam.sln -c Release
23+
24+
- name: Unit Test
25+
# No SECRET_SERVER_* env vars set — IntegrationFactAttribute auto-skips integration tests
26+
run: dotnet test delinea-secretserver-pam.Tests/delinea-secretserver-pam.Tests.csproj --no-build -c Release --logger "console;verbosity=normal"
27+
28+
integration-test:
29+
name: Integration Test
30+
runs-on: ubuntu-latest
31+
needs: unit-test
32+
# Skipped entirely when the environment hasn't been provisioned via Terraform
33+
if: vars.INTEGRATION_TESTS_ENABLED == 'true'
34+
environment: integration-tests
35+
steps:
36+
- uses: actions/checkout@v4
37+
38+
- uses: actions/setup-dotnet@v4
39+
with:
40+
dotnet-version: '10.x'
41+
42+
- name: Build
43+
run: dotnet build delinea-secretserver-pam.sln -c Release
44+
45+
- name: Integration Test
46+
run: dotnet test delinea-secretserver-pam.Tests/delinea-secretserver-pam.Tests.csproj --no-build -c Release --logger "console;verbosity=normal"
47+
env:
48+
SECRET_SERVER_URL: ${{ secrets.SECRET_SERVER_URL }}
49+
SECRET_SERVER_USERNAME: ${{ secrets.SECRET_SERVER_USERNAME }}
50+
SECRET_SERVER_PASSWORD: ${{ secrets.SECRET_SERVER_PASSWORD }}
51+
SECRET_SERVER_SECRET_ID: ${{ secrets.SECRET_SERVER_SECRET_ID }}
52+
SECRET_SERVER_SKIP_TLS_VALIDATION: ${{ vars.SECRET_SERVER_SKIP_TLS_VALIDATION }}
53+
KEYFACTOR_PAM_SKIP_TLS_VALIDATION: ${{ vars.SECRET_SERVER_SKIP_TLS_VALIDATION }}

terraform/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
terraform.tfvars
2+
.terraform/
3+
.terraform.lock.hcl
4+
*.tfstate
5+
*.tfstate.backup

terraform/backend.hcl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
resource_group_name = "rg-keyfactor-github-tfstate"
2+
storage_account_name = "kfghtfstatesn84ro"
3+
container_name = "tfstate"
4+
key = "github/repos/delinea-secretserver-pam/terraform.tfstate"

terraform/branch_protection.tf

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Ruleset ID 11607153 — "Protect default and release branches"
2+
# Covers ~DEFAULT_BRANCH and refs/heads/release-* (enforced, active).
3+
4+
resource "github_repository_ruleset" "protect_default_and_release" {
5+
name = "Protect default and release branches"
6+
repository = github_repository.repo.name
7+
target = "branch"
8+
enforcement = "active"
9+
10+
conditions {
11+
ref_name {
12+
include = ["~DEFAULT_BRANCH", "refs/heads/release-*"]
13+
exclude = []
14+
}
15+
}
16+
17+
bypass_actors {
18+
actor_id = null
19+
actor_type = "OrganizationAdmin"
20+
bypass_mode = "always"
21+
}
22+
23+
bypass_actors {
24+
actor_id = null
25+
actor_type = "DeployKey"
26+
bypass_mode = "always"
27+
}
28+
29+
bypass_actors {
30+
actor_id = 5
31+
actor_type = "RepositoryRole"
32+
bypass_mode = "always"
33+
}
34+
35+
rules {
36+
deletion = true
37+
non_fast_forward = true
38+
update = true
39+
40+
pull_request {
41+
required_approving_review_count = 0
42+
dismiss_stale_reviews_on_push = false
43+
require_code_owner_review = false
44+
require_last_push_approval = false
45+
required_review_thread_resolution = false
46+
}
47+
}
48+
}

terraform/import.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/usr/bin/env bash
2+
# Imports existing GitHub resources into Terraform state.
3+
# Run once after `terraform init -backend-config=backend.hcl`.
4+
# Safe to re-run — Terraform skips resources already in state.
5+
6+
set -euo pipefail
7+
8+
terraform import github_repository.repo delinea-secretserver-pam
9+
terraform import github_team_repository.integration_engineers integration-engineers:delinea-secretserver-pam
10+
terraform import github_team_repository.release_builders release_builders:delinea-secretserver-pam
11+
terraform import github_team_repository.private_access private-access:delinea-secretserver-pam
12+
terraform import github_repository_ruleset.protect_default_and_release \
13+
delinea-secretserver-pam:11607153

terraform/main.tf

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
locals {
2+
repo_name = "delinea-secretserver-pam"
3+
}
4+
5+
# ── Repository ────────────────────────────────────────────────────────────────
6+
7+
resource "github_repository" "repo" {
8+
name = local.repo_name
9+
description = "The Delinea Secret Server PAM Provider allows for the retrieval of stored account credentials from a Delinea Secret Server secret. A valid username, password and secret share settings are required."
10+
visibility = "public"
11+
12+
has_issues = true
13+
has_projects = true
14+
has_wiki = true
15+
has_discussions = false
16+
17+
allow_merge_commit = true
18+
allow_squash_merge = true
19+
allow_rebase_merge = true
20+
squash_merge_commit_title = "COMMIT_OR_PR_TITLE"
21+
squash_merge_commit_message = "COMMIT_MESSAGES"
22+
23+
delete_branch_on_merge = false
24+
allow_auto_merge = false
25+
26+
topics = ["keyfactor-pam"]
27+
}
28+
29+
resource "github_repository_dependabot_security_updates" "repo" {
30+
repository = github_repository.repo.id
31+
enabled = true
32+
}
33+
34+
# ── Team access ───────────────────────────────────────────────────────────────
35+
36+
resource "github_team_repository" "integration_engineers" {
37+
team_id = "4319508"
38+
repository = github_repository.repo.name
39+
permission = "push"
40+
}
41+
42+
resource "github_team_repository" "release_builders" {
43+
team_id = "6287033"
44+
repository = github_repository.repo.name
45+
permission = "admin"
46+
}
47+
48+
resource "github_team_repository" "private_access" {
49+
team_id = "5888166"
50+
repository = github_repository.repo.name
51+
permission = "pull"
52+
}
53+
54+
# ── Integration test environment ──────────────────────────────────────────────
55+
56+
resource "github_repository_environment" "integration_tests" {
57+
repository = github_repository.repo.name
58+
environment = "integration-tests"
59+
}
60+
61+
resource "github_actions_environment_secret" "secret_server_url" {
62+
repository = github_repository.repo.name
63+
environment = github_repository_environment.integration_tests.environment
64+
secret_name = "SECRET_SERVER_URL"
65+
value = var.secret_server_url
66+
}
67+
68+
resource "github_actions_environment_secret" "secret_server_username" {
69+
repository = github_repository.repo.name
70+
environment = github_repository_environment.integration_tests.environment
71+
secret_name = "SECRET_SERVER_USERNAME"
72+
value = var.secret_server_username
73+
}
74+
75+
resource "github_actions_environment_secret" "secret_server_password" {
76+
repository = github_repository.repo.name
77+
environment = github_repository_environment.integration_tests.environment
78+
secret_name = "SECRET_SERVER_PASSWORD"
79+
value = var.secret_server_password
80+
}
81+
82+
resource "github_actions_environment_secret" "secret_server_secret_id" {
83+
repository = github_repository.repo.name
84+
environment = github_repository_environment.integration_tests.environment
85+
secret_name = "SECRET_SERVER_SECRET_ID"
86+
value = var.secret_server_secret_id
87+
}
88+
89+
resource "github_actions_environment_variable" "skip_tls_validation" {
90+
repository = github_repository.repo.name
91+
environment = github_repository_environment.integration_tests.environment
92+
variable_name = "SECRET_SERVER_SKIP_TLS_VALIDATION"
93+
value = "true"
94+
}
95+
96+
# ── Repository variable to gate integration tests in CI ───────────────────────
97+
# When this variable is absent (no terraform apply yet), the integration-test
98+
# job in dotnet-ci.yml is skipped entirely via `if: vars.INTEGRATION_TESTS_ENABLED == 'true'`.
99+
100+
resource "github_actions_variable" "integration_tests_enabled" {
101+
repository = github_repository.repo.name
102+
variable_name = "INTEGRATION_TESTS_ENABLED"
103+
value = "true"
104+
}

terraform/outputs.tf

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
output "repository_url" {
2+
description = "HTTPS URL of the repository."
3+
value = github_repository.repo.html_url
4+
}
5+
6+
output "repository_ssh_clone_url" {
7+
description = "SSH clone URL."
8+
value = github_repository.repo.ssh_clone_url
9+
}
10+
11+
output "integration_tests_environment" {
12+
description = "Name of the GitHub environment used for integration tests."
13+
value = github_repository_environment.integration_tests.environment
14+
}

terraform/providers.tf

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
terraform {
2+
required_version = ">= 1.6"
3+
4+
required_providers {
5+
github = {
6+
source = "integrations/github"
7+
version = "~> 6.0"
8+
}
9+
azurerm = {
10+
source = "hashicorp/azurerm"
11+
version = "~> 3.0"
12+
}
13+
}
14+
15+
# Remote state in Azure Blob Storage (shared with other plugin repos).
16+
# Run: terraform init -backend-config=backend.hcl
17+
backend "azurerm" {}
18+
}
19+
20+
provider "github" {
21+
owner = "Keyfactor"
22+
token = var.github_token
23+
}
24+
25+
provider "azurerm" {
26+
features {}
27+
subscription_id = var.azure_subscription_id
28+
}

terraform/terraform.tfvars.example

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copy to terraform.tfvars and fill in real values.
2+
# terraform.tfvars is gitignored — never commit it.
3+
4+
github_token = "ghp_YOUR_PERSONAL_ACCESS_TOKEN"
5+
6+
# Optional — defaults to the Keyfactor Azure subscription
7+
# azure_subscription_id = "b3114ff1-bb92-45b6-9bd6-e4a1eed8c91e"
8+
9+
secret_server_url = "https://your-instance.secretservercloud.com/SecretServer"
10+
secret_server_username = ""
11+
secret_server_password = ""
12+
secret_server_secret_id = ""

terraform/variables.tf

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
variable "github_token" {
2+
description = "GitHub Personal Access Token with repo, admin:org, and workflow scopes."
3+
type = string
4+
sensitive = true
5+
}
6+
7+
variable "azure_subscription_id" {
8+
description = "Azure subscription ID for the Terraform remote state backend."
9+
type = string
10+
default = "b3114ff1-bb92-45b6-9bd6-e4a1eed8c91e"
11+
}
12+
13+
variable "secret_server_url" {
14+
description = "Delinea Secret Server base URL for integration tests."
15+
type = string
16+
sensitive = true
17+
}
18+
19+
variable "secret_server_username" {
20+
description = "Username for Secret Server integration test auth."
21+
type = string
22+
sensitive = true
23+
}
24+
25+
variable "secret_server_password" {
26+
description = "Password for Secret Server integration test auth."
27+
type = string
28+
sensitive = true
29+
}
30+
31+
variable "secret_server_secret_id" {
32+
description = "Secret ID to retrieve in integration tests."
33+
type = string
34+
}

0 commit comments

Comments
 (0)