Bootstrap #145
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Bootstrap | |
# Perform initial project setup to enable development of a new service | |
on: | |
workflow_dispatch: | |
inputs: | |
issue_number: | |
description: Issue number (e.g. PI-123) | |
required: true | |
type: string | |
project_name: | |
description: Project name | |
required: true | |
type: string | |
project_template: | |
description: Project template | |
required: true | |
type: choice | |
default: message-listener-with-api-client | |
options: | |
- api-client-and-server | |
- api-server | |
- message-listener | |
- message-listener-with-api-client | |
- message-listener-with-api-client-and-server | |
- 'No template - I want to create the project from scratch' | |
create_sentry_project: | |
description: Will the service use Sentry for capturing exceptions? | |
default: true | |
required: true | |
type: boolean | |
create_oauth_client: | |
description: Will the service consume another HTTP API that requires HMPPS Auth client credentials? | |
default: true | |
required: true | |
type: boolean | |
create_queue: | |
description: Will the service consume HMPPS domain event messages? | |
default: true | |
required: true | |
type: boolean | |
create_infra: | |
description: Will the service be deployed to MOJ Cloud Platform? | |
default: true | |
required: true | |
type: boolean | |
jobs: | |
auth-setup: | |
runs-on: ubuntu-latest | |
if: ${{ inputs.create_oauth_client }} | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Create issue for manual steps | |
run: | | |
gh issue create \ | |
--title "${{ inputs.issue_number }} Request HMPPS Auth client for ${{ inputs.project_name }}" \ | |
--body ' | |
- [ ] Clone Jira ticket: [HAAR-1662](https://dsdmoj.atlassian.net/browse/HAAR-1662) | |
- [ ] Raise in Slack: [#hmpps-auth-audit-registers](https://mojdt.slack.com/archives/C02S71KUBED)' \ | |
--label bootstrap | |
env: | |
GITHUB_TOKEN: ${{ github.token }} | |
project-setup: | |
if: ${{ inputs.project_template != 'No template - I want to create the project from scratch' }} | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/create-github-app-token@v1 | |
id: app-token | |
with: | |
repositories: hmpps-probation-integration-services,hmpps-probation-integration-e2e-tests | |
app-id: ${{ secrets.BOT_APP_ID }} | |
private-key: ${{ secrets.BOT_APP_PRIVATE_KEY }} | |
- uses: actions/checkout@v4 | |
with: | |
ref: main | |
token: ${{ steps.app-token.outputs.token }} | |
- name: Render project template | |
uses: ./.github/actions/render-project-template | |
with: | |
project_name: ${{ inputs.project_name }} | |
project_template: ${{ inputs.project_template }} | |
- name: Create pull request | |
id: pr | |
uses: ./.github/actions/create-signed-pull-request | |
with: | |
add-paths: | | |
settings.gradle.kts | |
.github/workflows | |
.idea/runConfigurations | |
doc/tech-docs | |
projects/${{ inputs.project_name }} | |
branch: bootstrap/${{ inputs.project_name }} | |
commit-message: ${{ inputs.issue_number }} Create initial project for ${{ inputs.project_name }} | |
token: ${{ steps.app-token.outputs.token }} | |
- uses: actions/checkout@v4 | |
with: | |
ref: main | |
path: hmpps-probation-integration-e2e-tests | |
repository: ministryofjustice/hmpps-probation-integration-e2e-tests | |
token: ${{ steps.app-token.outputs.token }} | |
- name: Update e2e test repo | |
run: sed -i '/add new projects here/i \ - '"'"'["${{ inputs.project_name }}"]'"'"'' hmpps-probation-integration-e2e-tests/.github/workflows/test-single-project.yml | |
- name: Create pull request | |
id: e2e-pr | |
uses: ./.github/actions/create-signed-pull-request | |
with: | |
path: hmpps-probation-integration-e2e-tests | |
add-paths: .github/workflows | |
branch: ${{ inputs.issue_number }}-create-${{ inputs.project_name }}-project | |
commit-message: ${{ inputs.issue_number }} Add option to run tests for ${{ inputs.project_name }} | |
token: ${{ steps.app-token.outputs.token }} | |
- name: Create issue for manual steps | |
run: | | |
gh issue create \ | |
--title "${{ inputs.issue_number }} Complete project setup for ${{ inputs.project_name }}" \ | |
--body ' | |
- [ ] Merge project pull request: ${{ steps.pr.outputs.pull-request-url }} | |
- [ ] Merge e2e tests pull request: ${{ steps.e2e-pr.outputs.pull-request-url }}' \ | |
--label bootstrap | |
env: | |
GITHUB_TOKEN: ${{ github.token }} | |
sentry-setup: | |
runs-on: ubuntu-latest | |
if: ${{ inputs.create_sentry_project }} | |
outputs: | |
project_slug: ${{ steps.project.outputs.slug }} | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Create project | |
id: project | |
run: | | |
response=$(curl https://sentry.io/api/0/teams/ministryofjustice/probation-integration/projects/ --fail \ | |
-H "Authorization: Bearer $SENTRY_AUTH_TOKEN" \ | |
-H 'Content-Type: application/json' --data '{"name":"${{ inputs.project_name }}"}') | |
echo "slug=$(echo "$response" | jq -r '.slug')" | tee -a "$GITHUB_OUTPUT" | |
env: | |
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} | |
- name: Set platform to Kotlin | |
run: | | |
curl -X PUT "https://sentry.io/api/0/projects/ministryofjustice/$SLUG/" --fail \ | |
-H "Authorization: Bearer $SENTRY_AUTH_TOKEN" \ | |
-H 'Content-Type: application/json' --data '{"platform":"kotlin"}' | |
env: | |
SLUG: ${{ steps.project.outputs.slug }} | |
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} | |
- name: Get client key id | |
id: client_key | |
run: | | |
response=$(curl "https://sentry.io/api/0/projects/ministryofjustice/$SLUG/keys/" --fail \ | |
-H "Authorization: Bearer $SENTRY_AUTH_TOKEN") | |
echo "id=$(echo "$response" | jq -r '.[0].id')" | tee -a "$GITHUB_OUTPUT" | |
env: | |
SLUG: ${{ steps.project.outputs.slug }} | |
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} | |
- name: Set rate limit (10/minute) | |
run: | | |
curl -X PUT "https://sentry.io/api/0/projects/ministryofjustice/$SLUG/keys/$KEY_ID/" --fail \ | |
-H "Authorization: Bearer $SENTRY_AUTH_TOKEN" \ | |
-H 'Content-Type: application/json' --data '{"rateLimit":{"count":10,"window":60}}' | |
env: | |
SLUG: ${{ steps.project.outputs.slug }} | |
KEY_ID: ${{ steps.client_key.outputs.id }} | |
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} | |
- name: Create alert for new issues | |
run: | | |
curl "https://sentry.io/api/0/projects/ministryofjustice/$SLUG/rules/?duplicateRule=true&wizardV3=true" --fail \ | |
-H "Authorization: Bearer $SENTRY_AUTH_TOKEN" \ | |
-H 'Content-Type: application/json' --data "$(jq --arg env "$env" --arg project_slug "$SLUG" -n '{ | |
"actionMatch": "any", | |
"actions": [ | |
{ | |
"channel": "probation-integration-notifications", | |
"channel_id": "C033HPR0W91", | |
"id": "sentry.integrations.slack.notify_action.SlackNotifyServiceAction", | |
"name": "Send a notification to the MOJ Digital & Technology Slack workspace to probation-integration-notifications (optionally, an ID: C033HPR0W91) and show tags [] in notification", | |
"tags": "environment", | |
"workspace": "50134" | |
} | |
], | |
"conditions": [ | |
{ "id": "sentry.rules.conditions.first_seen_event.FirstSeenEventCondition", "name": "A new issue is created" }, | |
{ "id": "sentry.rules.conditions.regression_event.RegressionEventCondition", "name": "The issue changes state from resolved to unresolved" }, | |
{ "id": "sentry.rules.conditions.reappeared_event.ReappearedEventCondition", "name": "The issue changes state from ignored to unresolved" } | |
], | |
"environment": null, | |
"filterMatch": "all", | |
"filters": [], | |
"frequency": 5, | |
"name": "New issues", | |
"owner": "team:1611212", | |
"projects": [$project_slug] | |
}')" | |
env: | |
SLUG: ${{ steps.project.outputs.slug }} | |
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} | |
sentry-secrets: | |
runs-on: ubuntu-latest | |
if: ${{ inputs.create_sentry_project }} | |
needs: sentry-setup | |
strategy: | |
matrix: | |
environment: [ "test", "preprod", "prod" ] | |
environment: ${{ matrix.environment }} | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: ./.github/actions/cloud-platform-auth | |
with: | |
api: ${{ secrets.KUBE_ENV_API }} | |
cert: ${{ secrets.KUBE_CERT }} | |
cluster: ${{ secrets.KUBE_CLUSTER }} | |
namespace: ${{ secrets.KUBE_NAMESPACE }} | |
token: ${{ secrets.KUBE_TOKEN }} | |
- name: Get client key DSN | |
id: client_key | |
run: | | |
response=$(curl "https://sentry.io/api/0/projects/ministryofjustice/$SLUG/keys/" --fail \ | |
-H "Authorization: Bearer $SENTRY_AUTH_TOKEN") | |
dsn=$(echo "$response" | jq -r '.[0].dsn.public') | |
echo "::add-mask::$dsn" | |
echo "dsn=$dsn" | tee -a "$GITHUB_OUTPUT" | |
env: | |
SLUG: ${{ needs.sentry-setup.outputs.project_slug }} | |
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} | |
- name: Store DSN as Kubernetes secret | |
run: kubectl create secret generic "$PROJECT-sentry" --from-literal "SENTRY_DSN=$VALUE" --from-literal "SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN" | |
env: | |
PROJECT: ${{ inputs.project_name }} | |
VALUE: ${{ steps.client_key.outputs.dsn }} | |
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} | |
sqs-queue-setup: | |
runs-on: ubuntu-latest | |
if: ${{ inputs.create_queue }} | |
steps: | |
- id: project_name | |
run: echo "with_underscores_uppercase=$(echo '${{ inputs.project_name }}' | sed 's/-/_/g' | tr '[:lower:]' '[:upper:]')" | tee -a "$GITHUB_OUTPUT" | |
- uses: actions/create-github-app-token@v1 | |
id: app-token | |
with: | |
repositories: cloud-platform-environments | |
app-id: ${{ secrets.BOT_EXTERNAL_REPOS_APP_ID }} | |
private-key: ${{ secrets.BOT_EXTERNAL_REPOS_APP_PRIVATE_KEY }} | |
- uses: actions/checkout@v4 | |
- uses: actions/checkout@v4 | |
with: | |
path: cloud-platform-environments-dev | |
repository: ministryofjustice/cloud-platform-environments | |
token: ${{ steps.app-token.outputs.token }} | |
- uses: actions/checkout@v4 | |
with: | |
path: cloud-platform-environments-preprod | |
repository: ministryofjustice/cloud-platform-environments | |
token: ${{ steps.app-token.outputs.token }} | |
- uses: actions/checkout@v4 | |
with: | |
path: cloud-platform-environments-prod | |
repository: ministryofjustice/cloud-platform-environments | |
token: ${{ steps.app-token.outputs.token }} | |
- name: Render Terraform queue template | |
run: | | |
sed 's/SERVICE_NAME_UPPERCASE/${{ steps.project_name.outputs.with_underscores_uppercase }}/g;s/SERVICE_NAME/${{ inputs.project_name }}/g' templates/sqs.tf > 'cloud-platform-environments-dev/namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-probation-integration-services-dev/resources/${{ inputs.project_name }}-queue.tf' | |
sed 's/SERVICE_NAME_UPPERCASE/${{ steps.project_name.outputs.with_underscores_uppercase }}/g;s/SERVICE_NAME/${{ inputs.project_name }}/g' templates/sqs.tf > 'cloud-platform-environments-preprod/namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-probation-integration-services-preprod/resources/${{ inputs.project_name }}-queue.tf' | |
sed 's/SERVICE_NAME_UPPERCASE/${{ steps.project_name.outputs.with_underscores_uppercase }}/g;s/SERVICE_NAME/${{ inputs.project_name }}/g' templates/sqs.tf > 'cloud-platform-environments-prod/namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-probation-integration-services-prod/resources/${{ inputs.project_name }}-queue.tf' | |
- name: Update IAM access to queues | |
run: | | |
sed -i '/queue = \[/a \ module.${{ inputs.project_name }}-queue,' 'cloud-platform-environments-dev/namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-probation-integration-services-dev/resources/iam.tf' | |
sed -i '/queue = \[/a \ module.${{ inputs.project_name }}-queue,' 'cloud-platform-environments-preprod/namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-probation-integration-services-preprod/resources/iam.tf' | |
sed -i '/queue = \[/a \ module.${{ inputs.project_name }}-queue,' 'cloud-platform-environments-prod/namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-probation-integration-services-prod/resources/iam.tf' | |
sed -i '/dlq = \[/a \ module.${{ inputs.project_name }}-dlq,' 'cloud-platform-environments-dev/namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-probation-integration-services-dev/resources/iam.tf' | |
sed -i '/dlq = \[/a \ module.${{ inputs.project_name }}-dlq,' 'cloud-platform-environments-preprod/namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-probation-integration-services-preprod/resources/iam.tf' | |
sed -i '/dlq = \[/a \ module.${{ inputs.project_name }}-dlq,' 'cloud-platform-environments-prod/namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-probation-integration-services-prod/resources/iam.tf' | |
- name: Create dev pull request | |
id: dev-pr | |
uses: ./.github/actions/create-signed-pull-request | |
with: | |
path: cloud-platform-environments-dev | |
add-paths: namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-probation-integration-services-dev | |
branch: ${{ inputs.issue_number }}-create-${{ inputs.project_name }}-queue-dev | |
commit-message: ${{ inputs.issue_number }} Create SQS queues for ${{ inputs.project_name }} (dev) | |
token: ${{ steps.app-token.outputs.token }} | |
- name: Create preprod pull request | |
id: preprod-pr | |
uses: ./.github/actions/create-signed-pull-request | |
with: | |
path: cloud-platform-environments-preprod | |
add-paths: namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-probation-integration-services-preprod | |
branch: ${{ inputs.issue_number }}-create-${{ inputs.project_name }}-queue-preprod | |
commit-message: ${{ inputs.issue_number }} Create SQS queues for ${{ inputs.project_name }} (preprod) | |
token: ${{ steps.app-token.outputs.token }} | |
- name: Create prod pull request | |
id: prod-pr | |
uses: ./.github/actions/create-signed-pull-request | |
with: | |
path: cloud-platform-environments-prod | |
add-paths: namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-probation-integration-services-prod | |
branch: ${{ inputs.issue_number }}-create-${{ inputs.project_name }}-queue-prod | |
commit-message: ${{ inputs.issue_number }} Create SQS queues for ${{ inputs.project_name }} (prod) | |
token: ${{ steps.app-token.outputs.token }} | |
- name: Create issue for manual steps | |
run: | | |
gh issue create \ | |
--title '${{ inputs.issue_number }} Complete queue setup for ${{ inputs.project_name }}' \ | |
--body ' | |
- [ ] Enter the event types the service will consume into the filter_policy for dev: [Edit file](https://github.com/ministryofjustice/cloud-platform-environments/edit/${{ inputs.issue_number }}-create-${{ inputs.project_name }}-queue-dev/namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-probation-integration-services-dev/resources/${{ inputs.project_name }}-queue.tf) | |
- [ ] Enter the event types the service will consume into the filter_policy for preprod: [Edit file](https://github.com/ministryofjustice/cloud-platform-environments/edit/${{ inputs.issue_number }}-create-${{ inputs.project_name }}-queue-preprod/namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-probation-integration-services-preprod/resources/${{ inputs.project_name }}-queue.tf) | |
- [ ] Enter the event types the service will consume into the filter_policy for prod: [Edit file](https://github.com/ministryofjustice/cloud-platform-environments/edit/${{ inputs.issue_number }}-create-${{ inputs.project_name }}-queue-prod/namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-probation-integration-services-prod/resources/${{ inputs.project_name }}-queue.tf) | |
- [ ] Request approval in [#ask-cloud-platform](https://mojdt.slack.com/archives/C57UPMZLY) | |
> ${{ steps.dev-pr.outputs.pull-request-url }} | |
> ${{ steps.preprod-pr.outputs.pull-request-url }} | |
> ${{ steps.prod-pr.outputs.pull-request-url }} | |
- [ ] Merge the pull requests' \ | |
--label bootstrap | |
env: | |
GITHUB_TOKEN: ${{ github.token }} | |
infra-setup: | |
runs-on: ubuntu-latest | |
if: ${{ inputs.create_infra }} | |
steps: | |
- id: project_name | |
run: echo "hash=$(echo -n '${{ inputs.project_name }}' | sha1sum | head -c 8)" | tee -a "$GITHUB_OUTPUT" | |
- uses: actions/create-github-app-token@v1 | |
id: app-token | |
with: | |
repositories: cloud-platform-environments | |
app-id: ${{ secrets.BOT_EXTERNAL_REPOS_APP_ID }} | |
private-key: ${{ secrets.BOT_EXTERNAL_REPOS_APP_PRIVATE_KEY }} | |
- uses: actions/checkout@v4 | |
- uses: actions/checkout@v4 | |
with: | |
path: cloud-platform-environments-dev | |
repository: ministryofjustice/cloud-platform-environments | |
token: ${{ steps.app-token.outputs.token }} | |
- uses: actions/checkout@v4 | |
with: | |
path: cloud-platform-environments-preprod | |
repository: ministryofjustice/cloud-platform-environments | |
token: ${{ steps.app-token.outputs.token }} | |
- uses: actions/checkout@v4 | |
with: | |
path: cloud-platform-environments-prod | |
repository: ministryofjustice/cloud-platform-environments | |
token: ${{ steps.app-token.outputs.token }} | |
- name: Add Pingdom check | |
run: sed -i '/add new projects here/i \ "${{ inputs.project_name }}",' 'cloud-platform-environments-prod/namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-probation-integration-services-prod/resources/pingdom.tf' | |
- name: Render certificate templates | |
run: | | |
sed 's/$SERVICE_NAME/${{ inputs.project_name }}/g;s/$SERVICE_URL/${{ inputs.project_name }}-dev.hmpps.service.justice.gov.uk/g;s/$SERVICE_SHORT_URL/${{ steps.project_name.outputs.hash }}-dev.hmpps.service.justice.gov.uk/g;s/$ENV/dev/g' templates/certificate.yml >> 'cloud-platform-environments-dev/namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-probation-integration-services-dev/05-certificates.yml' | |
sed 's/$SERVICE_NAME/${{ inputs.project_name }}/g;s/$SERVICE_URL/${{ inputs.project_name }}-preprod.hmpps.service.justice.gov.uk/g;s/$SERVICE_SHORT_URL/${{ steps.project_name.outputs.hash }}-preprod.hmpps.service.justice.gov.uk/g;s/$ENV/preprod/g' templates/certificate.yml >> 'cloud-platform-environments-preprod/namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-probation-integration-services-preprod/05-certificates.yml' | |
sed 's/$SERVICE_NAME/${{ inputs.project_name }}/g;s/$SERVICE_URL/${{ inputs.project_name }}.hmpps.service.justice.gov.uk/g;s/$SERVICE_SHORT_URL/${{ steps.project_name.outputs.hash }}.hmpps.service.justice.gov.uk/g;s/$ENV/prod/g' templates/certificate.yml >> 'cloud-platform-environments-prod/namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-probation-integration-services-prod/05-certificates.yml' | |
- name: Create dev pull request | |
id: dev-pr | |
uses: ./.github/actions/create-signed-pull-request | |
with: | |
path: cloud-platform-environments-dev | |
add-paths: namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-probation-integration-services-dev | |
branch: ${{ inputs.issue_number }}-create-${{ inputs.project_name }}-infra-dev | |
commit-message: ${{ inputs.issue_number }} Create certificate for ${{ inputs.project_name }} (dev) | |
token: ${{ steps.app-token.outputs.token }} | |
- name: Create preprod pull request | |
id: preprod-pr | |
uses: ./.github/actions/create-signed-pull-request | |
with: | |
path: cloud-platform-environments-preprod | |
add-paths: namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-probation-integration-services-preprod | |
branch: ${{ inputs.issue_number }}-create-${{ inputs.project_name }}-infra-preprod | |
commit-message: ${{ inputs.issue_number }} Create certificate for ${{ inputs.project_name }} (preprod) | |
token: ${{ steps.app-token.outputs.token }} | |
- name: Create prod pull request | |
id: prod-pr | |
uses: ./.github/actions/create-signed-pull-request | |
with: | |
path: cloud-platform-environments-prod | |
add-paths: namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-probation-integration-services-prod | |
branch: ${{ inputs.issue_number }}-create-${{ inputs.project_name }}-infra-prod | |
commit-message: ${{ inputs.issue_number }} Create Pingdom check and certificate for ${{ inputs.project_name }} (prod) | |
token: ${{ steps.app-token.outputs.token }} | |
- name: Create issue for manual steps | |
run: | | |
gh issue create \ | |
--title '${{ inputs.issue_number }} Complete infrastructure setup for ${{ inputs.project_name }}' \ | |
--body ' | |
- [ ] Request approval in [#ask-cloud-platform](https://mojdt.slack.com/archives/C57UPMZLY) for the following pull requests | |
> ${{ steps.dev-pr.outputs.pull-request-url }} | |
> ${{ steps.preprod-pr.outputs.pull-request-url }} | |
> ${{ steps.prod-pr.outputs.pull-request-url }} | |
- [ ] Merge the pull requests' \ | |
--label bootstrap | |
env: | |
GITHUB_TOKEN: ${{ github.token }} |