Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
50 changes: 50 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,56 @@ The following inputs can be used as `step.with` keys:
| `timeout` | `5m` | The timeout for the Helm command |
| `working-directory` | `.` | The working directory where the action commands will operate |

### Setup PostgreSQL Preview Schema

Sets up a PostgreSQL preview schema by cloning the main schema.

#### Example

```yaml
- uses: aboutbits/github-actions-kubernetes/setup-postgres-preview-schema@v3
with:
deployment-name: my-app
namespace: my-namespace
preview-number: ${{ github.event.number }}
```

#### Inputs

The following inputs can be used as `step.with` keys:

| Name | Required/Default | Description |
|-------------------|------------------|--------------------------------------------|
| `deployment-name` | required | Name of the deployment |
| `namespace` | required | Kubernetes namespace |
| `preview-number` | required | Preview number (PR number) |
| `secret-name` | `app-secrets` | Name of the secret containing PostgreSQL password |

### Teardown PostgreSQL Preview Schema

Drops the PostgreSQL preview schema.

#### Example

```yaml
- uses: aboutbits/github-actions-kubernetes/teardown-postgres-preview-schema@v3
with:
deployment-name: my-app
namespace: my-namespace
preview-number: ${{ github.event.number }}
```

#### Inputs

The following inputs can be used as `step.with` keys:

| Name | Required/Default | Description |
|-------------------|------------------|--------------------------------------------|
| `deployment-name` | required | Name of the deployment |
| `namespace` | required | Kubernetes namespace |
| `preview-number` | required | Preview number (PR number) |
| `secret-name` | `app-secrets` | Name of the secret containing PostgreSQL password |

## Build & Publish

To build and publish the action, visit the GitHub Actions page of the repository and trigger the workflow "Release Package" manually.
Expand Down
62 changes: 62 additions & 0 deletions setup-postgres-preview-schema/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: 'Setup PostgreSQL Preview Schema'
description: 'Sets up a PostgreSQL preview schema by cloning the main schema'
inputs:
deployment-name:
description: 'Name of the deployment (used for ConfigMap name)'
required: true
namespace:
description: 'Kubernetes namespace'
required: true
preview-number:
description: 'Preview number (PR number)'
required: true
secret-name:
description: 'Name of the secret containing DB password'
required: false
default: 'app-secrets'

runs:
using: "composite"
steps:
- name: Prepare setup-schema job
run: |
JOB_NAME="prepare-schema-preview-${{ inputs.preview-number }}"
CONFIGMAP_NAME="${{ inputs.deployment-name }}-environments"

# Create a temporary file for the manifest
cp ${{ github.action_path }}/job-template.yml job-setup-schema.yml

# Replace placeholders
sed -i "s/JOB_NAME_PLACEHOLDER/$JOB_NAME/g" job-setup-schema.yml
sed -i "s/CONFIGMAP_NAME_PLACEHOLDER/$CONFIGMAP_NAME/g" job-setup-schema.yml
sed -i "s/SECRET_NAME_PLACEHOLDER/${{ inputs.secret-name }}/g" job-setup-schema.yml
sed -i "s/PREVIEW_NUMBER_PLACEHOLDER/${{ inputs.preview-number }}/g" job-setup-schema.yml

echo "Prepared job manifest: job-setup-schema.yml"
shell: bash

- name: Create setup-schema job
run: |
kubectl apply --namespace ${{ inputs.namespace }} -f job-setup-schema.yml
shell: bash

- name: Wait for setup-schema job to complete
run: |
JOB_NAME="prepare-schema-preview-${{ inputs.preview-number }}"
NAMESPACE="${{ inputs.namespace }}"

echo "Waiting for job $JOB_NAME in namespace $NAMESPACE..."

if kubectl wait --namespace $NAMESPACE --for=condition=complete --timeout=60s job/$JOB_NAME; then
echo "Job finished with status: Complete"
kubectl logs job/$JOB_NAME --namespace $NAMESPACE
elif kubectl wait --namespace $NAMESPACE --for=condition=failed --timeout=1s job/$JOB_NAME; then
echo "Job finished with status: Failed"
kubectl logs job/$JOB_NAME --namespace $NAMESPACE
exit 1
else
echo "Timeout waiting for job to complete."
kubectl logs job/$JOB_NAME --namespace $NAMESPACE || true
exit 1
fi
shell: bash
85 changes: 85 additions & 0 deletions setup-postgres-preview-schema/job-template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
apiVersion: batch/v1
kind: Job
metadata:
name: JOB_NAME_PLACEHOLDER
spec:
ttlSecondsAfterFinished: 60
template:
spec:
restartPolicy: Never
containers:
- name: prepare-schema-preview

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- name: prepare-schema-preview
- name: prepare-preview-schema

I would switch the words since you have it also in other places.

image: postgres:18

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make this configurable with good defaults?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes we can.

command: [ "bash", "-c" ]
args:
- |
set -e

echo "### START $(date --iso-8601=seconds) ###"

if psql -t -A -c "SELECT 1 FROM information_schema.schemata WHERE schema_name = 'preview_$PREVIEW_NUMBER'" | grep -q 1; then
echo "Schema preview_$PREVIEW_NUMBER already exists. Skipping setup."
echo "Script finished successfully!"
echo "### END $(date --iso-8601=seconds) ###"
exit 0
fi
Comment on lines +23 to +28

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that you added this check 💪🏼


echo "Dumping schema $PGSCHEMA..."
pg_dump --schema=main \
--no-comments \
--no-owner \
--no-acl \
--quote-all-identifiers \
--format=plain \
--file=preview-dump.sql

echo "Modifying dump file..."
sed -i preview-dump.sql \
-e "s/\"main\"/\"preview_$PREVIEW_NUMBER\"/g" \
-e 's/SET /--SET /g' \
-e 's/SELECT pg_catalog/--SELECT pg_catalog/g' \
-e 's/--SELECT pg_catalog.setval/SELECT pg_catalog.setval/g'

echo "Creating schema preview_$PREVIEW_NUMBER with modified dump file..."
psql --echo-queries \
--echo-errors \
--single-transaction \
--set=ON_ERROR_STOP=1 \
--set=SESSION_REPLICATION_ROLE=replica \
--file=preview-dump.sql

echo "Script finished successfully!"
echo "### END $(date --iso-8601=seconds) ###"
env:
- name: PGHOST
valueFrom:
configMapKeyRef:
name: CONFIGMAP_NAME_PLACEHOLDER
key: DB_HOST
- name: PGPORT
valueFrom:
configMapKeyRef:
name: CONFIGMAP_NAME_PLACEHOLDER
key: DB_PORT
- name: PGDATABASE
valueFrom:
configMapKeyRef:
name: CONFIGMAP_NAME_PLACEHOLDER
key: DB_NAME
- name: PGSCHEMA
valueFrom:
configMapKeyRef:
name: CONFIGMAP_NAME_PLACEHOLDER
key: DB_SCHEMA
- name: PGUSER
valueFrom:
configMapKeyRef:
name: CONFIGMAP_NAME_PLACEHOLDER
key: DB_USERNAME
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: SECRET_NAME_PLACEHOLDER
key: DB_PASSWORD
- name: PREVIEW_NUMBER
value: "PREVIEW_NUMBER_PLACEHOLDER"
62 changes: 62 additions & 0 deletions teardown-postgres-preview-schema/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: 'Teardown PostgreSQL Preview Schema'
description: 'Drops the PostgreSQL preview schema'
inputs:
deployment-name:
description: 'Name of the deployment (used for ConfigMap name)'
required: true
namespace:
description: 'Kubernetes namespace'
required: true
preview-number:
description: 'Preview number (PR number)'
required: true
secret-name:
description: 'Name of the secret containing DB password'
required: false
default: 'app-secrets'

runs:
using: "composite"
steps:
- name: Prepare teardown-schema job
run: |
JOB_NAME="drop-schema-preview-${{ inputs.preview-number }}"
CONFIGMAP_NAME="${{ inputs.deployment-name }}-environments"

# Create a temporary file for the manifest
cp ${{ github.action_path }}/job-template.yml job-teardown-schema.yml

# Replace placeholders
sed -i "s/JOB_NAME_PLACEHOLDER/$JOB_NAME/g" job-teardown-schema.yml
sed -i "s/CONFIGMAP_NAME_PLACEHOLDER/$CONFIGMAP_NAME/g" job-teardown-schema.yml
sed -i "s/SECRET_NAME_PLACEHOLDER/${{ inputs.secret-name }}/g" job-teardown-schema.yml
sed -i "s/PREVIEW_NUMBER_PLACEHOLDER/${{ inputs.preview-number }}/g" job-teardown-schema.yml

echo "Prepared job manifest: job-teardown-schema.yml"
shell: bash

- name: Create teardown-schema job
run: |
kubectl apply --namespace ${{ inputs.namespace }} -f job-teardown-schema.yml
shell: bash

- name: Wait for teardown-schema job to complete
run: |
JOB_NAME="drop-schema-preview-${{ inputs.preview-number }}"
NAMESPACE="${{ inputs.namespace }}"

echo "Waiting for job $JOB_NAME in namespace $NAMESPACE..."

if kubectl wait --namespace $NAMESPACE --for=condition=complete --timeout=60s job/$JOB_NAME; then
echo "Job finished with status: Complete"
kubectl logs job/$JOB_NAME --namespace $NAMESPACE
elif kubectl wait --namespace $NAMESPACE --for=condition=failed --timeout=1s job/$JOB_NAME; then
echo "Job finished with status: Failed"
kubectl logs job/$JOB_NAME --namespace $NAMESPACE
exit 1
else
echo "Timeout waiting for job to complete."
kubectl logs job/$JOB_NAME --namespace $NAMESPACE || true
exit 1
fi
shell: bash
60 changes: 60 additions & 0 deletions teardown-postgres-preview-schema/job-template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
apiVersion: batch/v1
kind: Job
metadata:
name: JOB_NAME_PLACEHOLDER
spec:
ttlSecondsAfterFinished: 60
template:
spec:
restartPolicy: Never
containers:
- name: drop-preview-schema
image: postgres:18
command: [ "bash", "-c" ]
args:
- |
set -e

echo "### START $(date --iso-8601=seconds) ###"
echo "Drop schema preview_$PREVIEW_NUMBER..."
psql --echo-queries \
--echo-errors \
--single-transaction \
--set=ON_ERROR_STOP=1 \
--command="drop schema if exists preview_$PREVIEW_NUMBER cascade;"

echo "Script finished successfully!"
echo "### END $(date --iso-8601=seconds) ###"
env:
- name: PGHOST
valueFrom:
configMapKeyRef:
name: CONFIGMAP_NAME_PLACEHOLDER
key: DB_HOST
- name: PGPORT
valueFrom:
configMapKeyRef:
name: CONFIGMAP_NAME_PLACEHOLDER
key: DB_PORT
- name: PGDATABASE
valueFrom:
configMapKeyRef:
name: CONFIGMAP_NAME_PLACEHOLDER
key: DB_NAME
- name: PGSCHEMA
valueFrom:
configMapKeyRef:
name: CONFIGMAP_NAME_PLACEHOLDER
key: DB_SCHEMA
- name: PGUSER
valueFrom:
configMapKeyRef:
name: CONFIGMAP_NAME_PLACEHOLDER
key: DB_USERNAME
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: SECRET_NAME_PLACEHOLDER
key: DB_PASSWORD
- name: PREVIEW_NUMBER
value: "PREVIEW_NUMBER_PLACEHOLDER"