Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
5238397
init dynamic-staging-envs action
dapama Jul 1, 2025
ead28d7
check tf and opentofu versions within the with-inputs
dapama Jul 1, 2025
18e776a
test it with null value
dapama Jul 1, 2025
44fca27
feat: add support for OpenTofu version selection in terragrunt execution
dapama Jul 1, 2025
43126b7
add execute gcloud-sdk execute
dapama Jul 3, 2025
4d5998d
feat: add repository checkout step to GCP authentication workflow
dapama Jul 3, 2025
9b4ab1f
fix: remove debug logs and directly execute gcloud command in dynamic…
dapama Jul 3, 2025
2932b30
refactor: reorganize GCP authentication actions and update WIF config…
dapama Jul 7, 2025
d3f179f
fix: remove --project arg from setup-gcloud action
dapama Jul 8, 2025
7d23bc6
feat: add support for GCP service account JSON authentication alongsi…
dapama Jul 9, 2025
a46c428
refactor: simplify conditional expressions
dapama Jul 9, 2025
7f6e04a
feat: add project_id parameter to GCP authentication action
dapama Jul 10, 2025
cff462c
refactor: rename gcloud auth actions
dapama Jul 10, 2025
82bdd90
fix: remove http prefix from ArgoCD host default value
dapama Jul 10, 2025
1dfafc5
feat: enable terragrunt apply with auto-approve
dapama Jul 10, 2025
1344cc8
feat: enable terragrunt apply with auto-approve using numeric value
dapama Jul 10, 2025
48275e3
feat: add GKE configuration options and credentials setup to gcloud S…
dapama Jul 10, 2025
24290c7
fix: disable configure_gke by default
dapama Jul 10, 2025
cace496
feat: add dynamic SDK component installation based on GKE configuration
dapama Jul 10, 2025
01763dc
fix: correct environment variable name for gcloud SDK components inst…
dapama Jul 10, 2025
73ef980
fix: correct SDK components string interpolation in gcloud configurat…
dapama Jul 10, 2025
3bd12da
add: print kubectl version
dapama Jul 10, 2025
19802c6
feat: add configurable kubectl version and replace manual installatio…
dapama Jul 10, 2025
885f703
feat: add support for custom variables in terragrunt commands
dapama Jul 10, 2025
bd4099d
fix: relocate command_vars
dapama Jul 10, 2025
b752820
fix: correct variable handling in terragrunt command execution
dapama Jul 10, 2025
38384c4
fix: correctly parse and format terragrunt command variables with pro…
dapama Jul 11, 2025
9f7f2a6
fix: correct input variable name from terragrunt_command to terragrun…
dapama Jul 11, 2025
0278250
fix: add doble quotes for INPUT_COMMANDS
dapama Jul 11, 2025
44bb2c6
feat: add CloudSQL management actions for instance ownership, snapsho…
dapama Jul 14, 2025
8f534c6
fix: update gcloud-sdk-configure action path and echo SQL instance pa…
dapama Jul 14, 2025
90f21f7
fix: remove duplicated single quota inside if statement
dapama Jul 14, 2025
3ccd1d9
refactor: optimize GCP actions with conditional kubectl install and i…
dapama Jul 14, 2025
86d1d7c
fix: add missing 'then' keyword
dapama Jul 14, 2025
c9535b0
Add sleep for debug
samcre Jul 15, 2025
ee72466
Revert "Add sleep for debug"
samcre Jul 15, 2025
2cc0aa9
Enable apply
samcre Jul 15, 2025
1f429c5
Enable auto approve
samcre Jul 15, 2025
4702ba2
Enable start of instances
samcre Jul 16, 2025
3dc7e03
Enable restore of snapshots
samcre Jul 16, 2025
6c20c83
refactor: update CloudSQL actions with improved instance ownership an…
dapama Jul 21, 2025
e3eb9bb
feat: add step to test instance connection
dapama Jul 21, 2025
0450e3a
feat: add gcp-project-id input
dapama Jul 21, 2025
5e7d758
chore: remove echos and include gcp-project-id input
dapama Jul 21, 2025
b491718
feat: add remove snapshot user step
dapama Jul 21, 2025
964da7b
fix: rename all inputs to use - instead of _
dapama Jul 21, 2025
88701ec
feat: add gcp-project-id as input
dapama Jul 21, 2025
785a2d6
fix: indent psql queries
dapama Jul 21, 2025
fbd6a8f
fix: change SQL user creation to deletion in CloudSQL instance owner …
dapama Jul 21, 2025
2d75ca2
chore: comment remove-user step
dapama Jul 22, 2025
518152b
feat: add setup-k6 with dd integration action
dapama Jul 22, 2025
9578dab
feat: update deprecated dd action
dapama Jul 22, 2025
2d702f8
feat: add argo-workflow-wait action
dapama Sep 9, 2025
e9d302f
feat: add labels input for argo-workflows-wait action
dapama Sep 9, 2025
2933417
Merge branch 'main' into sc-23004-dynamic-staging-envs
dapama Sep 10, 2025
48e8524
feat: add terragrunt plan step for execute-terragrunt action
dapama Sep 10, 2025
733b828
create github workflow actions
dapama Sep 10, 2025
9934aaa
refactor: use environment variables for GitHub API calls
dapama Sep 10, 2025
33a2c25
refactor: group functions to make it simple
dapama Sep 10, 2025
b6e2adc
test: display workflow info
dapama Sep 10, 2025
55fa8bd
test: display more workflow info
dapama Sep 10, 2025
6223e59
test: display more workflow info
dapama Sep 10, 2025
43666e3
test: display more workflow info again
dapama Sep 10, 2025
1f64d2c
fix: add params to jq query
dapama Sep 10, 2025
d553158
test: check curl output to figure out http status
dapama Sep 10, 2025
dd736dd
fix: add missing =
dapama Sep 10, 2025
e10f305
test: add echoes
dapama Sep 10, 2025
9dc1c42
feat: add http status control
dapama Sep 10, 2025
00c0aab
chore: improve echo message
dapama Sep 10, 2025
f827229
fix: update wrong output refs
dapama Sep 10, 2025
8af55e2
fix: string format
dapama Sep 10, 2025
1c91554
fix: string format again
dapama Sep 10, 2025
2cee171
fix: string format again
dapama Sep 10, 2025
1b10fa9
docs: add some comments
dapama Sep 11, 2025
cb4588e
format code
dapama Sep 11, 2025
5eb6a49
updat -d args
dapama Sep 11, 2025
ee2eff7
format: use gh instead of curl
dapama Sep 11, 2025
9e400f3
include gh auth status step
dapama Sep 11, 2025
dd80748
test gh api request
dapama Sep 11, 2025
97110de
remove envs
dapama Sep 11, 2025
795bcb6
format gh query
dapama Sep 11, 2025
faeca9c
debug gh query
dapama Sep 11, 2025
41fa148
update gh api request
dapama Sep 12, 2025
24cc4c6
add gh auth token command for testing
dapama Sep 12, 2025
ffe4ec0
add gh login command for testing
dapama Sep 12, 2025
8f612ec
add < for token input
dapama Sep 12, 2025
6dbcefb
remove login command
dapama Sep 12, 2025
3c40c19
add generate gh token step
dapama Sep 12, 2025
7e55cb5
add owner and repositories inputs
dapama Sep 12, 2025
4fc0764
split action into 3 different github actions
dapama Sep 15, 2025
3ad3ebc
add output message
dapama Sep 15, 2025
0537499
fix typo
dapama Sep 15, 2025
9e5f47d
add gh watch workflow execution step
dapama Sep 15, 2025
0ab8eac
enable debug
dapama Sep 15, 2025
152f75a
set github_token input as required
dapama Sep 15, 2025
1fed7e1
add watch run logic
dapama Sep 16, 2025
c4bf203
add workflow user
dapama Sep 16, 2025
29ae525
control the workflow output
dapama Sep 16, 2025
deb13d2
Merge branch 'main' into sc-23004-dynamic-staging-envs
dapama Sep 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
name: 'Argo Workflows CLI Wait for workflow'
description: 'Argo Workflows commands for its CLI wait for workflow.'

inputs:
argo_namespace:
description: 'Argo Workflows namespace.'
required: false
default: 'argo-workflows'
argo_server:
description: 'Argo Workflows server URL.'
required: false
default: 'argo-workflows.stg.fcm.digital:443'
argo_token:
description: 'Argo Workflows auth token.'
required: true
environment:
description: 'Environment.'
required: true
labels:
description: 'Labels to be used for filtering.'
required: false
default: ''

runs:
using: "composite"
steps:
- id: workflow-wait
name: 'Argo Workflow Wait'
shell: bash
run: ${{ github.action_path }}/entrypoint.sh
env:
ARGO_NAMESPACE: ${{ inputs.argo_namespace }}
ARGO_SERVER: ${{ inputs.argo_server }}
ARGO_TOKEN: ${{ inputs.argo_token }}
ARGO_HTTP1: true
ARGO_SECURE: true
KUBECONFIG: /dev/null
ENVIRONMENTS: ${{ inputs.environments }}
LABELS: ${{ inputs.labels }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash

set -euo pipefail

if [[ -z $LABELS ]]; then
LABELS=""
else
LABELS="-l $LABELS"
fi

echo "Waiting for Argo Workflow to complete"
argo wait @latest -n $ENVIRONMENTS $LABELS
if [[ $? -eq 0 ]]; then
echo "Argo Workflow submitted successfully"
argo get @latest -n $ENVIRONMENTS $LABELS
else
echo "Argo Workflow failed"
exit 1
fi

93 changes: 93 additions & 0 deletions .github/actions/github/execute-manual-workflow/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
---
name: 'Execute Manual Workflow'
description: 'Execute a manual workflow based on .'

inputs:
branch_name:
description: 'The branch name to execute the workflow on.'
required: false
default: "master"
github_token:
description: 'The GitHub Token. (Required if github_app_id and github_app_private_key are not provided)'
required: true
github_organization_name:
description: 'The GitHub organization name.'
required: true
github_repository_name:
description: 'The repository name.'
required: true
workflow_id:
description: 'The workflow ID.'
required: true
workflow_inputs:
description: 'The workflow inputs. Valid format: "--field key1=value1 --field key2=value2"'
required: false
default: ""
workflow_watch:
description: 'Whether to watch the workflow run or not. If true, the workflow will wait for the new workflow to finish.'
required: false
default: "false"
# This input is necessary because `gh workflow run` doesn't return the database ID of the workflow run and `gh run watch` requires the database ID.
workflow_watch_name_filter:
description: 'Filter the workflow run by name (Only available if workflow_watch is true).'
required: false
default: ""
workflow_watch_user:
description: 'The user to watch the workflow run as (Only available if workflow_watch is true).'
required: false
default: ""

runs:
using: "composite"
steps:
- id: exec-workflow
name: Execute Workflow
env:
GH_TOKEN: ${{ inputs.github_token }}
run: |
gh workflow run ${{ inputs.workflow_id }} --repo ${{ inputs.github_organization_name }}/${{ inputs.github_repository_name }} --ref ${{ inputs.branch_name }} ${{ inputs.workflow_inputs }}
shell: bash

- id: watch-workflow
if: inputs.workflow_watch == 'true'
name: Watch Workflow
env:
GH_TOKEN: ${{ inputs.github_token }}
GH_OUTPUT_FILE_NAME: gh-output.json
run: |
echo "Waiting for new run to appear..."
for i in {1..12}; do
sleep 10
# Get the latest run of the workflow as the user specified
gh run list --workflow=${{ inputs.workflow_id }} --repo ${{ inputs.github_organization_name }}/${{ inputs.github_repository_name }} --limit=1 --user "${{ inputs.workflow_watch_user }}" --json name,databaseId,createdAt > $GH_OUTPUT_FILE_NAME

if [[ $? -ne 0 ]] || [ ! -f "$GH_OUTPUT_FILE_NAME" ] && [ ! -s "$GH_OUTPUT_FILE_NAME" ]; then
echo "Workflow run not found. Still waiting... ($i/12)"
continue
fi

WORKFLOW_RUN_TIMESTAMP=$(cat $GH_OUTPUT_FILE_NAME | jq '.[0].createdAt' | xargs -I {} date -d {} +%s)
CURRENT_TIMESTAMP=$(date +%s)

WORKFLOW_RUN_AGE=$((CURRENT_TIMESTAMP - WORKFLOW_RUN_TIMESTAMP))
if [[ $WORKFLOW_RUN_AGE -lt 120 ]]; then
echo "Workflow run found with age of $WORKFLOW_RUN_AGE seconds"

# Get the database ID of the workflow run
WORKFLOW_RUN_DBID=$(cat $GH_OUTPUT_FILE_NAME | jq --arg name "${{ inputs.workflow_watch_name_filter }}" '.[] | select(.name | contains($name))' | jq '.databaseId')

if [[ -z "$WORKFLOW_RUN_DBID" ]]; then
echo "Workflow run not found. Still waiting... ($i/12)"
continue
fi
echo "Workflow run found with database ID: $WORKFLOW_RUN_DBID"
break
else
echo "Workflow run not found. Still waiting... ($i/12)"
continue
fi
done

# Wait for the workflow to finish and exit with the same status.
gh run watch --repo ${{ inputs.github_organization_name }}/${{ inputs.github_repository_name }} $WORKFLOW_RUN_DBID --interval 15 --compact --exit-status
shell: bash
46 changes: 46 additions & 0 deletions .github/actions/github/generate-github-app-token/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
name: 'Generate GitHub App Token'
description: 'Generate a GitHub App token based on the GitHub App ID and private key.'

inputs:
github_app_id:
description: 'The GitHub App ID.'
required: true
github_app_private_key:
description: 'The GitHub App private key.'
required: true
github_organization_name:
description: 'The GitHub organization name.'
required: true
github_repositories:
description: 'The GitHub repositories names to grant access to.'
required: true

outputs:
gh_token:
description: 'The GitHub App token.'
value: ${{ steps.generate-gh-token.outputs.token }}

runs:
using: "composite"
steps:
- name: Generate a GH Token
id: generate-gh-token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ inputs.github_app_id }}
private-key: ${{ inputs.github_app_private_key }}
owner: ${{ inputs.github_organization_name }}
repositories: ${{ inputs.github_repositories }}

- name: Test Token
run: |
gh auth status
if [[ $? -ne 0 ]]; then
echo "Failed to get GitHub App Token using GH App ID: ${{ inputs.github_app_id }} credentials."
exit 1
else
echo "GitHub App Token generated successfully. Token saved to output 'gh_token'."
fi
shell: bash

47 changes: 47 additions & 0 deletions .github/actions/github/get-workflow-id/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
name: 'Get Workflow ID'
description: 'Get the ID of a GitHub workflow based on the workflow file name and repository.'

inputs:
github_token:
description: 'The GitHub Token.'
required: true
github_organization_name:
description: 'The GitHub organization name.'
required: true
github_repository_name:
description: 'The repository name.'
required: true
workflow_file_name:
description: 'The workflow file name.'
required: true

outputs:
workflow_id:
description: 'The workflow ID.'
value: ${{ steps.get-workflow-id.outputs.workflow_id }}

runs:
using: "composite"
steps:
- id: get-workflow-id
name: Get Workflow ID
env:
GH_TOKEN: ${{ inputs.github_token }}
GH_OUTPUT_FILE_NAME: gh-output.json
run: |
gh workflow list --repo ${{ inputs.github_organization_name }}/${{ inputs.github_repository_name }} --json id,path > $GH_OUTPUT_FILE_NAME

if [[ $? -ne 0 ]] || [ ! -f "$GH_OUTPUT_FILE_NAME" ] && [ ! -s "$GH_OUTPUT_FILE_NAME" ]; then
echo "Failed to list workflows"
exit 1
fi

WORKFLOW_ID=$(cat $GH_OUTPUT_FILE_NAME | jq --arg workflowFileName "${{ inputs.workflow_file_name }}" '.[] | select(.path | contains($workflowFileName))' | jq '.id')

if [[ $? -ne 0 ]] || [[ -z $WORKFLOW_ID ]]; then
echo "Failed to get workflow ID"
exit 1
fi
echo "workflow_id=$WORKFLOW_ID" >> $GITHUB_OUTPUT
shell: bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
---
name: 'CloudSQL Instance New Owner'
description: 'Reassign the owner of a CloudSQL instance to a new owner.'

inputs:
gcloud-sdk-configure:
description: 'Whether to configure GCloud SDK.'
required: false
default: 'false'
gcp-project-id:
description: 'The GCP project ID.'
required: true

app-name:
description: 'The name of the application.'
required: true
service-name:
description: 'The name of the specific service (part of the app-name).'
required: true
database-name:
description: 'The prefix name of the database.'
required: true

restore-environment:
description: 'The environment to which the instance is being restored.'
required: true
snapshot-environment:
description: 'The environment from which the snapshot was taken.'
required: true

restore-instance:
description: 'The CloudSQL instance ID to reassign the owner of.'
required: true
private-ip-instance:
description: 'The CloudSQL private IP of the restored instance.'
required: true

postgres-user-pwd:
description: 'The password for the PostgreSQL database.'
required: true
appname-user-pwd:
description: 'The password for the App User.'
required: true

runs:
using: "composite"
steps:
- id: gcloud-sdk-configure
if: inputs.gcloud-sdk-configure == 'true'
name: 'Configure GCloud SDK'
uses: fcm-digital/.github/.github/actions/google-cloud-platform/gcloud-sdk-configure@sc-23004-dynamic-staging-envs
with:
gcp-project-id: ${{ inputs.gcp-project-id }}

- id: restore-postgres-user-password
name: Restore Postgres User Password
env:
DESTINATION_INSTANCE_ID: ${{ inputs.restore-instance }}
PGUSER: 'postgres'
PGPASSWORD: ${{ inputs.postgres-user-pwd }}
shell: bash
run: gcloud sql users set-password "${PGUSER}" --instance="${DESTINATION_INSTANCE_ID}" --password=${PGPASSWORD} --project=${{ inputs.gcp-project-id }}

- id: create-app-user
name: 'Create database user and password'
env:
DESTINATION_INSTANCE_ID: ${{ inputs.restore-instance }}
PGUSER: '${{ inputs.service-name }}-${{ inputs.restore-environment }}'
PGPASSWORD: ${{ inputs.appname-user-pwd }}
shell: bash
run: gcloud sql users create "${PGUSER}" --instance="${DESTINATION_INSTANCE_ID}" --password=${PGPASSWORD} --project=${{ inputs.gcp-project-id }}

- id: install-psql
name: Install PostgreSQL Client
shell: bash
run: |
sudo apt-get update
sudo apt-get install --yes --no-install-recommends postgresql-client

- id: 'run-postgres-config'
name: 'Configure restored PostgreSQL database'
env:
PGPASSWORD: ${{ inputs.postgres-user-pwd }}
shell: bash
run: |-
psql --host=${{ inputs.private-ip-instance }} --port=5432 --username=postgres <<EOF
\x
GRANT "${{ inputs.service-name }}-${{ inputs.restore-environment }}" TO "postgres";
ALTER DATABASE "${{ inputs.database-name }}_${{ inputs.snapshot-environment }}" RENAME TO "${{ inputs.database-name }}_${{ inputs.restore-environment }}";
ALTER DATABASE "${{ inputs.database-name }}_${{ inputs.restore-environment }}" OWNER TO "${{ inputs.service-name }}-${{ inputs.restore-environment }}";
\c "${{ inputs.database-name }}_${{ inputs.restore-environment }}"
REASSIGN OWNED BY "${{ inputs.service-name }}-${{ inputs.snapshot-environment }}" TO "${{ inputs.service-name }}-${{ inputs.restore-environment }}";
EOF

# - id: 'remove-snapshot-app-user'
# name: Remove Snapshot App User
# env:
# DESTINATION_INSTANCE_ID: ${{ inputs.restore-instance }}
# PGUSER: '${{ inputs.service-name }}-${{ inputs.snapshot-environment }}'
# shell: bash
# run: gcloud sql users delete "${PGUSER}" --instance="${DESTINATION_INSTANCE_ID}" --project=${{ inputs.gcp-project-id }}
Loading