Skip to content

Commit

Permalink
Merge pull request #5 from opencrvs/environment-scripts
Browse files Browse the repository at this point in the history
Environment scripts
  • Loading branch information
euanmillar authored Nov 17, 2023
2 parents 6e7f1ce + c9ebe34 commit f0c2cf5
Show file tree
Hide file tree
Showing 20 changed files with 969 additions and 31 deletions.
64 changes: 64 additions & 0 deletions .github/workflows/backup-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Check backup(production)
run-name: Checking if a production backup exists ${{ github.event.inputs.backup-label }}
on:
workflow_dispatch:
inputs:
environment:
type: choice
description: Environment to check backup
required: true
default: 'production'
options:
- production
branch_name:
description: Branch to run workflow from
default: develop
required: true
backup-label:
description: Your Backup label
required: true
jobs:
check-backup:
environment: ${{ github.event.inputs.environment }}
runs-on: ubuntu-20.04
timeout-minutes: 60
strategy:
matrix:
node-version: [16.20.0]
steps:
- uses: actions/checkout@v2
if: github.event_name == 'workflow_dispatch'
with:
ref: '${{ github.event.inputs.branch_name }}'
#
# Uncomment if using VPN
#
#- name: Install openconnect ppa
# run: sudo add-apt-repository ppa:dwmw2/openconnect -y && sudo apt update

#- name: Install openconnect
# run: sudo apt install -y openconnect

#- name: Connect to VPN
# run: |
# echo "${{ secrets.VPN_PWD }}" | sudo openconnect -u ${{ secrets.VPN_USER }} --passwd-on-stdin --protocol=${{ secrets.VPN_PROTOCOL }} ${{ secrets.VPN_HOST }}:${{ secrets.VPN_PORT }} --servercert ${{ secrets.VPN_SERVERCERT }} --background

#- name: Test if IP is reachable
# run: |
# ping -c4 ${{ secrets.SSH_HOST }}

- name: Install SSH Key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.SSH_KEY }}
known_hosts: ${{ secrets.KNOWN_HOSTS }}

- name: Check backups in ${{ github.event.inputs.environment }}
id: backup-check
env:
SSH_USER: ${{ secrets.SSH_USER }}
SSH_HOST: ${{ secrets.BACKUP_HOST }}
REMOTE_DIR: ${{ vars.BACKUP_DIRECTORY }}
LABEL: ${{ github.event.inputs.backup-label }}
run: |
yarn backup:check
37 changes: 34 additions & 3 deletions .github/workflows/deploy-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ on:
core-image-tag:
description: Core DockerHub image tag
required: true
default: 'v1.3.1'
default: 'v1.3.2'
countryconfig-image-tag:
description: Your Country Config DockerHub image tag
required: true
Expand Down Expand Up @@ -57,6 +57,23 @@ jobs:
cd opencrvs-core
git checkout ${{ github.event.inputs.core-image-tag }}
#
# Uncomment if using VPN
#
#- name: Install openconnect ppa
# run: sudo add-apt-repository ppa:dwmw2/openconnect -y && sudo apt update

#- name: Install openconnect
# run: sudo apt install -y openconnect

#- name: Connect to VPN
# run: |
# echo "${{ secrets.VPN_PWD }}" | sudo openconnect -u ${{ secrets.VPN_USER }} --passwd-on-stdin --protocol=${{ secrets.VPN_PROTOCOL }} ${{ secrets.VPN_HOST }}:${{ secrets.VPN_PORT }} --servercert ${{ secrets.VPN_SERVERCERT }} --background

#- name: Test if IP is reachable
# run: |
# ping -c4 ${{ secrets.SSH_HOST }}

- name: Install SSH Key
uses: shimataro/ssh-key-action@v2
with:
Expand All @@ -67,7 +84,7 @@ jobs:
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
password: ${{ secrets.DOCKER_TOKEN }}

- name: Wait for images to be available
run: |
Expand Down Expand Up @@ -96,6 +113,8 @@ jobs:
ALERT_EMAIL: ${{ secrets.ALERT_EMAIL }}
DOCKERHUB_ACCOUNT: ${{ secrets.DOCKERHUB_ACCOUNT }}
DOCKERHUB_REPO: ${{ secrets.DOCKERHUB_REPO }}
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }}
KIBANA_USERNAME: ${{ secrets.KIBANA_USERNAME }}
KIBANA_PASSWORD: ${{ secrets.KIBANA_PASSWORD }}
MONGODB_ADMIN_USER: ${{ secrets.MONGODB_ADMIN_USER }}
Expand All @@ -110,7 +129,19 @@ jobs:
INFOBIP_API_KEY: ${{ secrets.INFOBIP_API_KEY }}
SENDER_EMAIL_ADDRESS: ${{ secrets.SENDER_EMAIL_ADDRESS }}
SUPER_USER_PASSWORD: ${{ secrets.SUPER_USER_PASSWORD }}
SSH_KEY: ${{ secrets.SSH_KEY }}
KNOWN_HOSTS: ${{ secrets.KNOWN_HOSTS }}
CONTENT_SECURITY_POLICY_WILDCARD: ${{ vars.CONTENT_SECURITY_POLICY_WILDCARD }}
# SUDO_PASSWORD: ${{ secrets.SUDO_PASSWORD }}
# ELASTALERT_SLACK_WEBHOOK: ${{ secrets.ELASTALERT_SLACK_WEBHOOK }}
run: |
cd ./${{ github.event.repository.name }}
yarn deploy --clear_data=no --environment=${{ github.event.inputs.deploy-script-environment }} --host=${{ env.DOMAIN }} --version=${{ github.event.inputs.core-image-tag }} --country_config_version=${{ github.event.inputs.countryconfig-image-tag }} --country_config_path=../${{ github.event.repository.name }} --replicas=${{ env.REPLICAS }}
yarn deploy \
--clear_data=no \
--environment=${{ github.event.inputs.deploy-script-environment }} \
--host=${{ env.DOMAIN }} \
--ssh_host=${{ secrets.SSH_HOST }} \
--ssh_user=${{ secrets.SSH_USER }} \
--version=${{ github.event.inputs.core-image-tag }} \
--country_config_version=${{ github.event.inputs.countryconfig-image-tag }} \
--replicas=${{ env.REPLICAS }}
37 changes: 34 additions & 3 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ on:
core-image-tag:
description: Core DockerHub image tag
required: true
default: 'v1.3.1'
default: 'v1.3.2'
countryconfig-image-tag:
description: Your Country Config DockerHub image tag
required: true
Expand Down Expand Up @@ -60,6 +60,23 @@ jobs:
cd opencrvs-core
git checkout ${{ github.event.inputs.core-image-tag }}
#
# Uncomment if using VPN
#
#- name: Install openconnect ppa
# run: sudo add-apt-repository ppa:dwmw2/openconnect -y && sudo apt update

#- name: Install openconnect
# run: sudo apt install -y openconnect

#- name: Connect to VPN
# run: |
# echo "${{ secrets.VPN_PWD }}" | sudo openconnect -u ${{ secrets.VPN_USER }} --passwd-on-stdin --protocol=${{ secrets.VPN_PROTOCOL }} ${{ secrets.VPN_HOST }}:${{ secrets.VPN_PORT }} --servercert ${{ secrets.VPN_SERVERCERT }} --background

#- name: Test if IP is reachable
# run: |
# ping -c4 ${{ secrets.SSH_HOST }}

- name: Install SSH Key
uses: shimataro/ssh-key-action@v2
with:
Expand All @@ -70,7 +87,7 @@ jobs:
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
password: ${{ secrets.DOCKER_TOKEN }}

- name: Wait for images to be available
run: |
Expand Down Expand Up @@ -99,6 +116,8 @@ jobs:
ALERT_EMAIL: ${{ secrets.ALERT_EMAIL }}
DOCKERHUB_ACCOUNT: ${{ secrets.DOCKERHUB_ACCOUNT }}
DOCKERHUB_REPO: ${{ secrets.DOCKERHUB_REPO }}
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }}
KIBANA_USERNAME: ${{ secrets.KIBANA_USERNAME }}
KIBANA_PASSWORD: ${{ secrets.KIBANA_PASSWORD }}
MONGODB_ADMIN_USER: ${{ secrets.MONGODB_ADMIN_USER }}
Expand All @@ -113,10 +132,22 @@ jobs:
INFOBIP_API_KEY: ${{ secrets.INFOBIP_API_KEY }}
SENDER_EMAIL_ADDRESS: ${{ secrets.SENDER_EMAIL_ADDRESS }}
SUPER_USER_PASSWORD: ${{ secrets.SUPER_USER_PASSWORD }}
SSH_KEY: ${{ secrets.SSH_KEY }}
KNOWN_HOSTS: ${{ secrets.KNOWN_HOSTS }}
CONTENT_SECURITY_POLICY_WILDCARD: ${{ vars.CONTENT_SECURITY_POLICY_WILDCARD }}
# SUDO_PASSWORD: ${{ secrets.SUDO_PASSWORD }}
# ELASTALERT_SLACK_WEBHOOK: ${{ secrets.ELASTALERT_SLACK_WEBHOOK }}
run: |
cd ./${{ github.event.repository.name }}
yarn deploy --clear_data=${{ github.event.inputs.reset }} --environment=${{ github.event.inputs.environment }} --host=${{ env.DOMAIN }} --version=${{ github.event.inputs.core-image-tag }} --country_config_version=${{ github.event.inputs.countryconfig-image-tag }} --country_config_path=../${{ github.event.repository.name }} --replicas=${{ env.REPLICAS }}
yarn deploy \
--clear_data=${{ github.event.inputs.reset }} \
--environment=${{ github.event.inputs.environment }} \
--host=${{ env.DOMAIN }} \
--ssh_host=${{ secrets.SSH_HOST }} \
--ssh_user=${{ secrets.SSH_USER }} \
--version=${{ github.event.inputs.core-image-tag }} \
--country_config_version=${{ github.event.inputs.countryconfig-image-tag }} \
--replicas=${{ env.REPLICAS }}
seed-data:
needs: deploy
if: ${{ github.event.inputs.reset == 'yes' && needs.deploy.outputs.outcome == 'success' }}
Expand Down
150 changes: 150 additions & 0 deletions .github/workflows/provision.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
name: Provision environment
run-name: Provision ${{ github.event.inputs.environment }}
on:
workflow_dispatch:
inputs:
environment:
type: choice
description: Machine to provision
default: qa
required: true
options:
- staging
- qa
- production
branch_name:
description: Branch to provision from
default: develop
required: true

jobs:
provision:
environment: ${{ github.event.inputs.environment }}
runs-on: ubuntu-20.04
outputs:
outcome: ${{ steps.deploy.outcome }}
timeout-minutes: 60
strategy:
matrix:
node-version: [16.20.0]
steps:
- name: Clone country config resource package
uses: actions/checkout@v3
with:
fetch-depth: 0
path: './${{ github.event.repository.name }}'

- name: Set environment type ENV_TYPE
run: |
if [ "${{ github.event.inputs.environment }}" == "production" ]; then
echo "ENV_TYPE=production" >> "$GITHUB_ENV"
else
echo "ENV_TYPE=qa" >> "$GITHUB_ENV"
fi
#
# Uncomment if using VPN
#
#- name: Install openconnect ppa
# run: sudo add-apt-repository ppa:dwmw2/openconnect -y && sudo apt update

#- name: Install openconnect
# run: sudo apt install -y openconnect

#- name: Connect to VPN
# run: |
# echo "${{ secrets.VPN_PWD }}" | sudo openconnect -u ${{ secrets.VPN_USER }} --passwd-on-stdin --protocol=${{ secrets.VPN_PROTOCOL }} ${{ secrets.VPN_HOST }}:${{ secrets.VPN_PORT }} --servercert ${{ secrets.VPN_SERVERCERT }} --background

#- name: Test if IP is reachable
# run: |
# ping -c4 ${{ secrets.SSH_HOST }}

- name: Set variables for ansible in production environments
id: ansible-production-variables
if: env.ENV_TYPE == 'production'
run: |
JSON_WITH_NEWLINES=$(cat<<EOF
${{ toJSON(env) }}
EOF)
JSON_WITHOUT_NEWLINES=$(echo $JSON_WITH_NEWLINES | jq -R -c .)
echo "EXTRA_VARS=$JSON_WITHOUT_NEWLINES" >> $GITHUB_OUTPUT
env:
encrypted_disk_size: ${{ vars.DISK_SPACE }}
disk_encryption_key: ${{ secrets.ENCRYPTION_KEY }}
dockerhub_username: ${{ secrets.DOCKER_USERNAME }}
dockerhub_password: ${{ secrets.DOCKER_TOKEN }}
mongodb_admin_username: ${{ secrets.MONGODB_ADMIN_USER }}
mongodb_admin_password: ${{ secrets.MONGODB_ADMIN_PASSWORD }}
elasticsearch_superuser_password: ${{ secrets.ELASTICSEARCH_SUPERUSER_PASSWORD }}
external_backup_server_remote_directory: ${{ vars.BACKUP_DIRECTORY }}
external_backup_server_user: ${{ secrets.SSH_USER }}
external_backup_server_ssh_port: 22
external_backup_server_ip: ${{ secrets.BACKUP_HOST }}
manager_production_server_ip: ${{ secrets.SSH_HOST }}
ansible_user: ${{ secrets.SSH_USER }}
# ansible_sudo_pass: ${{ secrets.SUDO_PASSWORD }} in case your user is not root

- name: Set variables for ansible in qa environments
id: ansible-variables
if: env.ENV_TYPE == 'qa'
run: |
JSON_WITH_NEWLINES=$(cat<<EOF
${{ toJSON(env) }}
EOF)
JSON_WITHOUT_NEWLINES=$(echo $JSON_WITH_NEWLINES | jq -R -c .)
echo "EXTRA_VARS=$JSON_WITHOUT_NEWLINES" >> $GITHUB_OUTPUT
env:
encrypted_disk_size: ${{ vars.DISK_SPACE }}
disk_encryption_key: ${{ secrets.ENCRYPTION_KEY }}
dockerhub_username: ${{ secrets.DOCKER_USERNAME }}
dockerhub_password: ${{ secrets.DOCKER_TOKEN }}
mongodb_admin_username: ${{ secrets.MONGODB_ADMIN_USER }}
mongodb_admin_password: ${{ secrets.MONGODB_ADMIN_PASSWORD }}
elasticsearch_superuser_password: ${{ secrets.ELASTICSEARCH_SUPERUSER_PASSWORD }}
# ansible_sudo_pass: ${{ secrets.SUDO_PASSWORD }} in case your user is not root

# TODO: Iterate for 3 or 5 replicas
- name: Create ini file for 1 replica
id: ini-file
run: |
touch ${{ github.event.repository.name }}/infrastructure/server-setup/replicas-1.ini
echo "[docker-manager-first]" > ${{ github.event.repository.name }}/infrastructure/server-setup/replicas-1.ini
echo "manager1 ansible_host=\"${{ secrets.SSH_HOST }}\" ansible_user=${{ secrets.SSH_USER }} ansible_ssh_private_key_file=/tmp/server.pem" >> ${{ github.event.repository.name }}/infrastructure/server-setup/replicas-1.ini
echo "" >> ${{ github.event.repository.name }}/infrastructure/server-setup/replicas-1.ini
echo "[all:vars]" >> ${{ github.event.repository.name }}/infrastructure/server-setup/replicas-1.ini
echo "data1_hostname=${{ vars.HOSTNAME }}" >> ${{ github.event.repository.name }}/infrastructure/server-setup/replicas-1.ini
- name: Check ini content
run: |
cat ${{ github.event.repository.name }}/infrastructure/server-setup/replicas-1.ini
- name: Run playbook on 1 replica in qa
uses: dawidd6/action-ansible-playbook@v2
if: vars.REPLICAS == 1 && env.ENV_TYPE == 'qa'
env:
ANSIBLE_PERSISTENT_COMMAND_TIMEOUT: 30
ANSIBLE_SSH_TIMEOUT: 30
ANSIBLE_SSH_RETRIES: 20
with:
playbook: playbook-1.yml
directory: ${{ github.event.repository.name }}/infrastructure/server-setup
options: |
--verbose
--inventory replicas-1.ini
--extra-vars ""${{ steps.ansible-variables.outputs.EXTRA_VARS }}""
- name: Run playbook on 1 replica in production
uses: dawidd6/action-ansible-playbook@v2
if: vars.REPLICAS == 1 && env.ENV_TYPE == 'production'
env:
ANSIBLE_PERSISTENT_COMMAND_TIMEOUT: 30
ANSIBLE_SSH_TIMEOUT: 30
ANSIBLE_SSH_RETRIES: 20
with:
playbook: playbook-1.yml
directory: ${{ github.event.repository.name }}/infrastructure/server-setup
options: |
--verbose
--inventory replicas-1.ini
--extra-vars ""${{ steps.ansible-production-variables.outputs.EXTRA_VARS }}""
2 changes: 1 addition & 1 deletion .github/workflows/publish-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Push image
env:
DOCKERHUB_ACCOUNT: ${{ secrets.DOCKERHUB_ACCOUNT }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-to-dockerhub.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Push image
env:
DOCKERHUB_ACCOUNT: ${{ secrets.DOCKERHUB_ACCOUNT }}
Expand Down
3 changes: 3 additions & 0 deletions infrastructure/authorized_keys
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDYclwfSSTNDFaxX+tSZRbxw1kuTuhw5E3XvYC9HvOv828fMLlUEklSt+lfQLI8qaPqHO4NQaW0P4a3BM/IVoXc8jXyaItr7i143RL/lRy7wERiZJ83EKd8cb3pN5u3tG3ciAzA98xllUNPOuireZ7HYXqS/96/ITz3lZtWZ1QI413APee9le8z6VfPXgb/e+EVYvsqJGRKa5eWZMvkzzUnkI7cFGCxTM/sS0Aez1RCy7hZbBG9pOVOdHswGEXQQgwJTrigRAwp1HEhsbTgVHHlDnZlM+gmcjGpW7OgTDKGDgKqsHJp/uIHXftCa+/cSllA8xeLPrv0IWpmXD98HQybl32oU21XRKutR0EvOAblzLCS0SPKb9nuY8aAmnrt9Si9UyJxMeMOoaABs5/XAGHmSGrzKgbxXyNMrd9t21hF11PWi3PM/SMj9LGyW9+aw8qDMhUmTuzbfxoklESp61aik8QqLS9z8Pauq4XfPUhMPX/1H1Raa/TPPHOC2aKOhrU= nafiu@DESKTOP-K9VRGPP
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDECqHO65UpyrrO8uueD06RxGaVVq22f152Rf8qVQQAAIGAMu6gCs7ztlZ8a3yQgSEIjM/Jl1/RqIVs6CziTEef74nLFTZ5Ufz3CLRVgdebBeSBEmhTfTUV0HLkSyNzwKFpuzJxucGd72ulPvEp6eHvyJAPJz37YcU8cjaL1v05T6s2ee99li35GlDDtCzfjVV4ZPAg5JdfWuTj41RAVC0LQhk2/NB4qEu37UxGGjhRFSjBEsS5LxI9QfvgrsHpl/VOn+soH7ZkK7kS6qRgNP/uYsXRWXhHaamcl5OX68gJWTbrW6c7PCqlbCWGnsHJswCmqPIthwXXMfC7ULDNLSKG6mslAt5Dyc8/MCr3vTW7pDyr2d0FvvY86SMQUggxv3qF7TZewqfX1bhK0fMLarIxVMQ1RFo//wN9QGA+2we8rxd2Y1Kr1DBuJyuwXPfv+Exo8yNYQ+x/AYH5k6UVcSYuaB8eYmplG2KQCxt8RBFtoChrwOKNRWLqXdKyfpdp5XmnnWxPvR95gf3h3yLocVYkF0i0uvKKJ0vt8J0Ezfkdfow0B1kUg5bPXKJROX7PwbaCPdYcxyDaO6wwOigRnSmoFvkH1pLb4j1RQAXcX531CHgfN6Izi/h0mpMS4bnyIUcv2GQr+h4z4TxcCtj7qpH2y6yw7XG12jVh7TfeesXG2Q== [email protected]
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDD1cap8psIi1wBHMKEufhXkME0MGxNifINbdJTbWyeJzQvYJALUHYAi1vt37jEXp9QvvmzUZry4Rh8zW598ZkXGhRejGXCx5kkXYYT2YX4xMTuoRmg/dxxkIpXwDkDxU06WUUw1ObRX8wbjJvO/r5QLYReUtR4R5O6Ac7WPe9KzdGrbm7Whqa+WOrSsXLmoqtqW1EuLKOKP73Ajwe8bSe2sghC42G2sBw9bb4sAUlAzdhC7XC9pIUTC7IRCfyvNt0wjv+BrnUexT1TztdQnTuQe65PHmhA6UFp9JBKwhwhqpm7idXyLZruEd4Y+aLN/aHWeQQhOp0lydzxAJerQ/KsLTUlS04kOnoeiUENrra6ItY0mW2C3iCO23Nm3wsUtXSxTze0CebUK2Ly1eO5gDNE4bOoMK+N/OjV1S/7fHeAXewCyyVNjL/0m6Jx0aDFTshxFFEfswR/wUIxwPogetcpyiV3CG2Mww/tO2j2Eyw7qZLKBhUOuz/xaeTRIb3FhS0= asaph@asaph-HP-ProBook-450-15-6-inch-G9-Notebook-PC
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDKHo6hJmE2ww1/thnZ6AEHNLCyTvZT1aMGoxNsvmmemLtDe9JvSB8CN874L+OzgEgHkI2MNm4u6MQW1c7evw043hSEjijzr964xsG7l1+GXasH1/p+6Tz/KDYNW31nnD7xakmZmoDTAkEFDj7IDL5vG2paw30rLvsvC526Zh8C12ndj8dz+b6h/k3ndGAdMzVPzvh55UwaX2jktXDOxQj+8ncelMWfIFStRYlwxB47a3CMBNycvhGSw5aUivKCxog10nIepgyHy4kjEI5+uBOcwUAkQ35KFO6aqHVt7uoLcA0pmeJGFrQLKGuAKWRF5z686UpT15ZaFC02ezySmAjQv7P5JFcuyy2cop6c+uTOi2DmvS+EUS55ggUyIk/uwexOiWuUteHrTw9ywUNI/PIgFUkCAOWl7cpasF3XR5tsHOLCPPW71pimwRK1QO/cwT5aVBy8ISVOzdSsuM3brMDJWLFOpJpQ+Lw4gvc2QiIJgVuPY9g6AoUeo/4I6TeV4Bs= aline@aline-HP-ProBook-450-15-6-inch-G9-Notebook-PC

Loading

0 comments on commit f0c2cf5

Please sign in to comment.