Skip to content

split up the step into multiple steps #136

split up the step into multiple steps

split up the step into multiple steps #136

---
name: Test Changes with Cloned DB
on:
pull_request:
types: [ labeled, synchronize, closed ]
push:
permissions:
contents: read
jobs:
test_with_clone:
runs-on: ubuntu-latest
if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip_cloning') && github.event.pull_request.state == 'open' }}
environment: dev
env:
# Establish the snowflake account credentials
SNOWFLAKE_ACCOUNT: ${{ secrets.SNOWSQL_ACCOUNT }}
SNOWFLAKE_USER: ${{ secrets.SNOWSQL_USER }}
SNOWFLAKE_PASSWORD: ${{ secrets.SNOWSQL_PWD }}
# Establish the account roles to be used
SNOWFLAKE_ADMIN_ROLE: "${{ vars.SNOWFLAKE_SYNAPSE_DATA_WAREHOUSE_DATABASE }}_ADMIN"
SNOWFLAKE_CLONE_ROLE: DATA_ENGINEER
# Establish the domains
SNOWFLAKE_DOMAIN_ORIGINAL: ${{ vars.SNOWFLAKE_SYNAPSE_DATA_WAREHOUSE_DATABASE }}
SNOWFLAKE_DOMAIN_CLONE: "${{ vars.SNOWFLAKE_SYNAPSE_DATA_WAREHOUSE_DATABASE }}_${{ github.head_ref }}"
# Establish other miscellaneous variables
SNOWFLAKE_WAREHOUSE: ${{ secrets.SNOWSQL_WAREHOUSE }}
SNOWFLAKE_SYNAPSE_STAGE_STORAGE_INTEGRATION: ${{ vars.SNOWFLAKE_SYNAPSE_STAGE_STORAGE_INTEGRATION }}
SNOWFLAKE_SYNAPSE_STAGE_URL: ${{ vars.SNOWFLAKE_SYNAPSE_STAGE_URL }}
STACK: ${{ vars.STACK }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install python libraries
shell: bash
run: |
pip install schemachange==3.6.1
pip install numpy==1.26.4
pip install pandas==1.5.3
- name: Configure Snowflake connections
run: |
# Make a temporary config file for the GH runner
config_file=$(mktemp)
# Configurations for DATA_ENGINEER
echo 'default_connection_name = "dpe"' >> $config_file
echo '[connections.dpe]' >> $config_file
echo "account = \"${SNOWFLAKE_ACCOUNT}\"" >> $config_file
echo "user = \"${SNOWFLAKE_USER}\"" >> $config_file
echo "role = \"${SNOWFLAKE_CLONE_ROLE}\"" >> $config_file
echo "password = \"${SNOWFLAKE_PASSWORD}\"" >> $config_file
echo "warehouse = \"${SNOWFLAKE_WAREHOUSE}\"" >> $config_file
echo 'authenticator = "SNOWFLAKE"' >> $config_file
# Config file for *ADMIN
echo '[connections.admin]' >> $config_file
echo "account = \"${SNOWFLAKE_ACCOUNT}\"" >> $config_file
echo "user = \"${SNOWFLAKE_USER}\"" >> $config_file
echo "role = \"${SNOWFLAKE_ADMIN_ROLE}\"" >> $config_file
echo "password = \"${SNOWFLAKE_PASSWORD}\"" >> $config_file
echo "warehouse = \"${SNOWFLAKE_WAREHOUSE}\"" >> $config_file
echo 'authenticator = "SNOWFLAKE"' >> $config_file
# Write config paths to environment
echo "SNOWFLAKE_CONFIG_PATH=$config_file" >> $GITHUB_ENV
- name: Install Snowflake CLI with DATA_ENGINEER config
uses: Snowflake-Labs/[email protected]
with:
default-config-file-path: ${{ env.SNOWFLAKE_CONFIG_PATH }}
- name: Verify Snowflake CLI installation and connections
run: |
snow --version
snow connection test -c admin
snow connection test -c dpe
- name: Sanitize Clone Name
run: |
# Sanitize the clone name. That is, replace all non-alphanumeric characters with an underscore.
# Then create a new environment variable with the sanitized clone name to use in subsequent steps.
SNOWFLAKE_DOMAIN_CLONE_SANITIZED="${SNOWFLAKE_DOMAIN_CLONE//[^a-zA-Z0-9_]/_}"
echo "Clone name has been updated! The clone name will be: ${SNOWFLAKE_DOMAIN_CLONE_SANITIZED}"
echo "SNOWFLAKE_DOMAIN_CLONE_SANITIZED=${SNOWFLAKE_DOMAIN_CLONE_SANITIZED}" >> $GITHUB_ENV
# Next, create the environment variable: SNOWFLAKE_SYNAPSE_DATA_WAREHOUSE_DATABASE
# which schemachange uses to deploy changes to the right database (this is used in the schemachange step)
echo "SNOWFLAKE_SYNAPSE_DATA_WAREHOUSE_DATABASE=${SNOWFLAKE_DOMAIN_CLONE_SANITIZED}" >> $GITHUB_ENV
- name: Zero-copy clone the database as ADMIN
shell: bash
run: |
snow connection set-default admin
snow sql -q "CREATE OR REPLACE DATABASE ${SNOWFLAKE_DOMAIN_CLONE_SANITIZED} CLONE ${SNOWFLAKE_DOMAIN_ORIGINAL};"
- name: Establish full account role name for PROXY_ADMIN
shell: bash
run: |
snow connection set-default admin
# The *PROXY_ADMIN account role will be used to manage interschema objects (e.g. tasks, dynamic tables)
# within the cloned database. First let's create the PROXY_ADMIN account role name and export for immediate use:
echo "SNOWFLAKE_PROXY_ADMIN_ROLE=${SNOWFLAKE_DOMAIN_CLONE_SANITIZED}_PROXY_ADMIN" >> $GITHUB_ENV
- name: Create account role PROXY_ADMIN
shell: bash
run: |
snow connection set-default admin
snow sql -q "CREATE OR REPLACE ROLE ${SNOWFLAKE_PROXY_ADMIN_ROLE};"
- name: Transfer ownership of current and future tasks and dynamic tables to PROXY_ADMIN
shell: bash
run: |
snow connection set-default admin
# First let's transfer ownership of CURRENT tasks and dynamic tables to PROXY_ADMIN role
snow sql -q "GRANT OWNERSHIP ON ALL TASKS IN SCHEMA ${SNOWFLAKE_DOMAIN_CLONE_SANITIZED}.SYNAPSE_RAW TO ROLE ${SNOWFLAKE_PROXY_ADMIN_ROLE};"
snow sql -q "GRANT OWNERSHIP ON ALL DYNAMIC TABLES IN SCHEMA ${SNOWFLAKE_DOMAIN_CLONE_SANITIZED}.SYNAPSE TO ROLE ${SNOWFLAKE_PROXY_ADMIN_ROLE};"
# Next let's transfer ownership of FUTURE tasks and dynamic tables to PROXY_ADMIN role
snow sql -q "GRANT OWNERSHIP ON FUTURE TASKS IN SCHEMA ${SNOWFLAKE_DOMAIN_CLONE_SANITIZED}.SYNAPSE_RAW TO ROLE ${SNOWFLAKE_PROXY_ADMIN_ROLE};"
snow sql -q "GRANT OWNERSHIP ON FUTURE DYNAMIC TABLES IN SCHEMA ${SNOWFLAKE_DOMAIN_CLONE_SANITIZED}.SYNAPSE TO ROLE ${SNOWFLAKE_PROXY_ADMIN_ROLE};"
- name: Handle grants for objects/roles pertaining to cloned database for DATA_ENGINEER
shell: bash
run: |
snow connection set-default admin
# Revoke USAGE from: <DOMAIN>_ADMIN account role
snow sql -q "REVOKE USAGE ON DATABASE ROLE ${SNOWFLAKE_DOMAIN_CLONE_SANITIZED}.SYNAPSE_ALL_ADMIN FROM ROLE ${SNOWFLAKE_ADMIN_ROLE};"
snow sql -q "REVOKE USAGE ON DATABASE ROLE ${SNOWFLAKE_DOMAIN_CLONE_SANITIZED}.SYNAPSE_RAW_ALL_ADMIN FROM ROLE ${SNOWFLAKE_ADMIN_ROLE};"
snow sql -q "REVOKE USAGE ON DATABASE ROLE ${SNOWFLAKE_DOMAIN_CLONE_SANITIZED}.SCHEMACHANGE_ALL_ADMIN FROM ROLE ${SNOWFLAKE_ADMIN_ROLE};"
# Transfer OWNERSHIP of: *ALL_ADMIN aggregate database roles (for each namespace/schema)
snow sql -q "GRANT OWNERSHIP ON DATABASE ROLE ${SNOWFLAKE_DOMAIN_CLONE_SANITIZED}.SYNAPSE_ALL_ADMIN TO ROLE ${SNOWFLAKE_CLONE_ROLE};"
snow sql -q "GRANT OWNERSHIP ON DATABASE ROLE ${SNOWFLAKE_DOMAIN_CLONE_SANITIZED}.SYNAPSE_RAW_ALL_ADMIN TO ROLE ${SNOWFLAKE_CLONE_ROLE};"
snow sql -q "GRANT OWNERSHIP ON DATABASE ROLE ${SNOWFLAKE_DOMAIN_CLONE_SANITIZED}.SCHEMACHANGE_ALL_ADMIN TO ROLE ${SNOWFLAKE_CLONE_ROLE};"
# Transfer OWNERSHIP of: <CLONE-DOMAIN>_PROXY_ADMIN account role
snow sql -q "GRANT OWNERSHIP ON ROLE ${SNOWFLAKE_PROXY_ADMIN_ROLE} TO ROLE ${SNOWFLAKE_CLONE_ROLE};"
- name: Run schemachange on the clone as DATA_ENGINEER
shell: bash
run: |
schemachange \
-f synapse_data_warehouse \
-a $SNOWFLAKE_ACCOUNT \
-u $SNOWFLAKE_USER \
-r $SNOWFLAKE_CLONE_ROLE \
-w $SNOWFLAKE_WAREHOUSE \
--config-folder synapse_data_warehouse
drop_clone:
runs-on: ubuntu-latest
if: github.event.pull_request.merged == true || github.event.action == 'closed'
environment: dev
env:
# Establish the snowflake account credentials
SNOWFLAKE_ACCOUNT: ${{ secrets.SNOWSQL_ACCOUNT }}
SNOWFLAKE_USER: ${{ secrets.SNOWSQL_USER }}
SNOWFLAKE_PASSWORD: ${{ secrets.SNOWSQL_PWD }}
# Establish the account roles to be used
SNOWFLAKE_ADMIN_ROLE: "${{ vars.SNOWFLAKE_SYNAPSE_DATA_WAREHOUSE_DATABASE }}_ADMIN"
# Establish the domains
SNOWFLAKE_DOMAIN_CLONE: "${{ vars.SNOWFLAKE_SYNAPSE_DATA_WAREHOUSE_DATABASE }}_${{ github.head_ref }}"
# Establish the warehouse
SNOWFLAKE_WAREHOUSE: ${{ secrets.SNOWSQL_WAREHOUSE }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Configure Snowflake connection
run: |
# Make a temporary config file for the GH runner
config_file=$(mktemp)
# Config file for *ADMIN
echo 'default_connection_name = "admin"' >> $config_file
echo '[connections.admin]' >> $config_file
echo "account = \"${SNOWFLAKE_ACCOUNT}\"" >> $config_file
echo "user = \"${SNOWFLAKE_USER}\"" >> $config_file
echo "role = \"${SNOWFLAKE_ADMIN_ROLE}\"" >> $config_file
echo "password = \"${SNOWFLAKE_PASSWORD}\"" >> $config_file
echo "warehouse = \"${SNOWFLAKE_WAREHOUSE}\"" >> $config_file
echo 'authenticator = "SNOWFLAKE"' >> $config_file
# Write config paths to environment
echo "SNOWFLAKE_CONFIG_PATH=$config_file" >> $GITHUB_ENV
- name: Install Snowflake CLI
uses: Snowflake-Labs/[email protected]
with:
default-config-file-path: ${{ env.SNOWFLAKE_CONFIG_PATH }}
- name: Verify Snowflake CLI installation and connections
run: |
snow --version
snow connection test -c admin
- name: Sanitize Clone Name
run: |
SNOWFLAKE_DOMAIN_CLONE_SANITIZED="${SNOWFLAKE_DOMAIN_CLONE//[^a-zA-Z0-9_]/_}"
echo "Clone name has been updated! The clone name will be: ${SNOWFLAKE_DOMAIN_CLONE_SANITIZED}"
echo "SNOWFLAKE_DOMAIN_CLONE_SANITIZED=${SNOWFLAKE_DOMAIN_CLONE_SANITIZED}" >> $GITHUB_ENV
- name: Drop the clone
shell: bash
run: |
snow sql -r $SNOWFLAKE_ADMIN_ROLE -q "DROP DATABASE IF EXISTS ${SNOWFLAKE_DOMAIN_CLONE_SANITIZED};"