Skip to content

Symfony flavor

Symfony flavor #694

Workflow file for this run

################################################################################################
# This workflow attempts to test the steps a user is instructed to go through while deploying
# the Upsun demo project.
################################################################################################
name: Upsun Demo CI
'on':
pull_request:
branches:
- main
types:
- labeled
env:
UPSUN_CLI_NO_INTERACTION: 1
UPSUN_CLI_TOKEN: ${{secrets.DEVREL_USER_UPSUN_TOKEN}}
PHP_VERSION: '8.3'
UPSUN_HOST_REGION: "ca-1"
UPSUN_HOST_SUFFIX: "platform.sh"
UPSUN_USERNAME: "devrel-projects"
GIT_USER_EMAIL: "[email protected]"
GIT_USER_NAME: "DevRel Team Bot"
TEST_PATH: "utils/tests"
ORG_NAME: "demo-test-org"
PROJECT_LOCALDIR: "upsun-demo"
PROJECT_REPO: "platformsh/demo-project"
PROJECT_TITLE: 'Demo Test Run (pr-${{ github.ref_name }})'
DEFAULT_BRANCH: '${{ github.event.pull_request.head.ref }}'
STAGING_SUFFIX: '-staging'
STAGING_BRANCH: '${{ github.event.pull_request.head.ref }}$STAGING_SUFFIX'
DEFAULT_BRANCH_CHAR_LIMIT: 28
SLEEP: 5
BACKEND_PATH: "api/v1/environment"
BLACKFIRE_CLIENT_ID: '${{ secrets.DEVREL_USER_BLACKFIRE_CLIENT_ID }}'
BLACKFIRE_CLIENT_TOKEN: '${{ secrets.DEVREL_USER_BLACKFIRE_CLIENT_TOKEN }}'
jobs:
demo-runthrough:
runs-on: ubuntu-latest
if: ${{ github.event.label.name == 'runthrough' }}
steps:
################################################################################################
# A. Setup Upsun CLI, variables, & other tools.
- name: "[tools] 1. Retrieve local files."
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
# Original Upsun CLI
# - name: "[tools] 2. Set up Homebrew."
# id: set-up-homebrew
# uses: Homebrew/actions/setup-homebrew@master
# - name: "[tools] 3. Install Upsun CLI."
# run: |
# echo "::notice::Installing Upsun CLI via HomeBrew."
# brew install platformsh/tap/upsun-cli
# - name: "[tools] 4. Test: The Upsun CLI should be installed and executable."
# run: |
# echo "::notice::Verifying CLI is installed correctly."
# ./$TEST_PATH/command_installed.sh upsun
# Symfony variation
- name: "[tools] 2. Set up Homebrew."
id: set-up-homebrew
uses: Homebrew/actions/setup-homebrew@master
- name: "[tools] 3. Install Symfony CLI + Upsun CLI."
run: |
echo "::notice::Installing Symfony CLI via HomeBrew."
brew install symfony-cli/tap/symfony-cli
brew install platformsh/tap/upsun-cli
- name: "[tools] 4. Test: The Symfony CLI should be installed and executable."
run: |
echo "::notice::Verifying CLI is installed correctly."
./$TEST_PATH/command_installed.sh symfony
./$TEST_PATH/command_installed.sh upsun
- name: "[tools] 5. Test: Setup Blackfire."
uses: shivammathur/setup-php@v2
with:
php-version: ${{ env.PHP_VERSION }}
extensions: 'blackfire, :xdebug'
tools: 'blackfire, blackfire-player'
- name: "[tools] 6. Test: Setup Default Branch variables."
id: branch_names
run: |
echo "::notice::Ensure branch names are not too long."
if [ "${#DEFAULT_BRANCH}" -gt "$DEFAULT_BRANCH_CHAR_LIMIT" ]; then
echo "Branch name too long"
echo $DEFAULT_BRANCH, "len ${#DEFAULT_BRANCH}", "max $DEFAULT_BRANCH_CHAR_LIMIT"
count=$(($DEFAULT_BRANCH_CHAR_LIMIT-${#STAGING_SUFFIX}-1))
short="${DEFAULT_BRANCH:0:$count}"
DEFAULT_BRANCH="${short}"
STAGING_BRANCH="${short}${STAGING_SUFFIX}"
fi
echo "default_branch=${DEFAULT_BRANCH}" >> $GITHUB_OUTPUT
echo "staging_branch=${STAGING_BRANCH}" >> $GITHUB_OUTPUT
################################################################################################
# B. Setup authenticated Upsun CLI user.
- name: "[setup_cli_auth] 1. Test: an authenticated CLI can retrieve bot user info."
run: |
echo "::notice::Verifying CLI auth - bot can access user info."
RESULT=$(symfony auth:info username)
./$TEST_PATH/compare_strings.sh "$RESULT" "$UPSUN_USERNAME" "Authenticate Upsun CLI user"
- name: "[setup_cli_auth] 2. Test: an authenticated CLI can retrieve organization info."
run: |
echo "::notice::Verifying CLI auth - bot can access test organization info."
RESULT=$(symfony org:info -o $ORG_NAME name)
./$TEST_PATH/compare_strings.sh "$RESULT" "$ORG_NAME" "Authenticate Upsun CLI user"
- name: "[setup_cli_auth] 2. Authenticate Upsun CLI to allow push from workflow."
run: |
echo "::notice::Generating SSH certificate for Upsun CLI."
symfony ssh-cert:load --new -y
touch ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
ssh-keyscan ssh.$UPSUN_HOST_REGION.$UPSUN_HOST_SUFFIX -v >> ~/.ssh/known_hosts
ssh-keyscan git.$UPSUN_HOST_REGION.$UPSUN_HOST_SUFFIX -v >> ~/.ssh/known_hosts
################################################################################################
# C. Setup local repo.
- name: "[setup_repo] 1. Clone repository into runner."
run: |
echo "::notice::Cloning repo copy into runner."
cmd=$(cat frontend/src/commands.json | jq -r ".first_deploy.test.clone")
eval "$cmd"
- name: "[setup_repo] 2. Setup runner Git user."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
echo "::notice::Setting up Git user."
git config --global user.email "$GIT_USER_EMAIL"
git config --global user.name "$GIT_USER_NAME"
git branch -m ${{ steps.branch_names.outputs.default_branch }}
git branch --show-current
- name: "[setup_repo] 3. Test: Verify Git settings."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
echo "::notice::Verifying Git settings."
RESULT=$(git config --global user.email)
./$TEST_PATH/compare_strings.sh "$RESULT" "$GIT_USER_EMAIL" "Git config (email)"
RESULT=$(git config --global user.name)
./$TEST_PATH/compare_strings.sh "$RESULT" "$GIT_USER_NAME" "Git config (name)"
RESULT=$(git branch --show-current)
./$TEST_PATH/compare_strings.sh "$RESULT" "${{ steps.branch_names.outputs.default_branch }}" "Git branch"
################################################################################################
# D. Create project. Connect to local repo. Provide access to bot user to the project.
- name: "[create_project] 1. Create a project in the test organization."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
echo "::notice::Creating a project in the test organization."
echo "::notice::The project should become a remote repository for the local repo automatically."
symfony upsun:create -o "$ORG_NAME" \
--title "$PROJECT_TITLE" \
--region "$UPSUN_HOST_REGION.$UPSUN_HOST_SUFFIX" \
--default-branch ${{ steps.branch_names.outputs.default_branch }}
- name: "[create_project] 2. Test: The create project activity should complete."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.default_branch }} project.create state complete "create_project"
- name: "[create_project] 3. Test: The create project activity should succeed."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.default_branch }} project.create result success "create_project"
- name: "[create_project] 4. Test: project remote has been set."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
ADDRESS=$(git config remote.upsun.url)
PROJECT_ID=$(symfony upsun:project:info id)
EXPECTED="$PROJECT_ID@git.$UPSUN_HOST_REGION.$UPSUN_HOST_SUFFIX:$PROJECT_ID.git"
./$TEST_PATH/compare_strings.sh "$ADDRESS" "$EXPECTED" "project:set-remote git_address"
- name: "[create_project] 5. Test: project remote has been set. Ensure only a single project is defined in org for the current PR."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
# Failure here indicates that a project for another run on the same PR still exists in the org.
EXPECTED=$(symfony upsun:project:list -o "$ORG_NAME" --title "$PROJECT_TITLE" --pipe)
RESULT=$(symfony upsun project:info id)
./$TEST_PATH/compare_strings.sh "$RESULT" "$EXPECTED" "project:set-remote local"
- name: "[create_project] 6. Remove remote origin."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
git remote remove origin
# @todo: I can't quite get this test to work.
# - name: "[create_project] 7. Test: project is only remote defined on repo."
# working-directory: ${{ env.PROJECT_LOCALDIR }}
# run: |
# # @todo: this test breaks on failure, rather than providing a testable, empty string.
# ADDRESS=$(git config remote.origin.url)
# EXPECTED=""
# ./$TEST_PATH/compare_strings.sh "$ADDRESS" "$EXPECTED" "remote remove origin"
- name: "[create_project] 7. Update production environment name."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
symfony upsun:environment:info title "Production (${{ steps.branch_names.outputs.default_branch }})" -e ${{ steps.branch_names.outputs.default_branch }}
# @todo: The tests here are sound, but it takes a moment to get the final complete/success. Some kind of wait is probably
# needed here to 1) if pending --> wait until max, 2) if success, pass test, 3) if fail, fail test.
# The wait logic can be applied for all activity outcomes for 'state'.
# - name: "[create_project] 8. Test: The create production environment access should complete."
# working-directory: ${{ env.PROJECT_LOCALDIR }}
# run: |
# # @todo: a sleep seems to be required here.
# sleep 5
# upsun activity:list
# ./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.default_branch }} environment_type.access.create state complete "add_bot_user"
# - name: "[create_project] 9. Test: The create production environment access should succeed."
# working-directory: ${{ env.PROJECT_LOCALDIR }}
# run: |
# ./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.default_branch }} environment_type.access.create result success "add_bot_user"
- name: "[create_project] 10. Test: verify user has been granted access to project."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
ACTIVITY_TYPE="environment_type.access.create"
ACTIVITY_ID=$(symfony upsun:activity:list --type $ACTIVITY_TYPE --limit 1 --no-header --columns=id --format plain)
EXPECTED=$(symfony upsun:activity:get $ACTIVITY_ID -P parameters.target)
RESULT=$(symfony upsun:auth:info id)
./$TEST_PATH/compare_strings.sh "$RESULT" "$EXPECTED" "bot_user_add access"
ACTIVITY_TYPE="environment_type.access.create"
ACTIVITY_ID=$(symfony upsun:activity:list --type $ACTIVITY_TYPE --limit 1 --no-header --columns=id --format plain)
EXPECTED=$(symfony upsun:activity:get $ACTIVITY_ID -P parameters.role)
RESULT="admin"
./$TEST_PATH/compare_strings.sh "$RESULT" "$EXPECTED" "bot_user_add role"
################################################################################################
# E. First code deploy.
- name: "[first_deploy] 1. Deploy the demo application to Upsun."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
echo "::notice::First push to project."
# @todo: Push through Git, not the CLI, so the exit doesn't break the workflow.
export DEFAULT_BRANCH=${{ steps.branch_names.outputs.default_branch }}
git push --force upsun ${{ steps.branch_names.outputs.default_branch }}
cmd=$(cat frontend/src/commands.json | jq -r ".first_deploy.test.push")
eval "$cmd"
# upsun push -f -y
- name: "[first_deploy] 2. Test: The first deploy activity should complete."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.default_branch }} push state complete "first_push"
- name: "[first_deploy] 3. Test: The first deploy activity should succeed."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.default_branch }} push result success "first_push"
- name: "[first_deploy] 4. Test: Test responses on demo app using Blackfire Player."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
cmd=$(cat frontend/src/commands.json | jq -r ".first_deploy.user.get_url")
eval "$cmd"
URL=$(eval "$cmd --pipe")
sleep $SLEEP
blackfire-player run blackfire.yaml --endpoint="$URL" --variable step=branch -vvv
################################################################################################
# F. Create staging environment.
- name: "[environment_branch] 1. Create preview environment"
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
symfony upsun branch ${{ steps.branch_names.outputs.staging_branch }} --type staging
- name: "[environment_branch] 2. Test: The environment_branch activity should complete."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.staging_branch }} environment.branch state complete "environment_branch"
- name: "[environment_branch] 3. Test: The environment_branch activity should succeed."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.staging_branch }} environment.branch result success "environment_branch"
- name: "[environment_branch] 4. Test: Test responses on demo app using Blackfire Player."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
URL=$(symfony upsun url --primary --pipe)
sleep $SLEEP
blackfire-player run blackfire.yaml --endpoint="$URL" --variable step=redis -vvv
- name: "[environment_branch] 5. Update staging environment name."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
symfony upsun environment:info title "Staging (${{ steps.branch_names.outputs.staging_branch }})" -e ${{ steps.branch_names.outputs.staging_branch }}
################################################################################################
# G. Add a service.
- name: "[add_service] 1. Uncomment service configuration block. Commit & push new service."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/uncomment.sh .upsun/config.yaml add_service
export STAGING_BRANCH=${{ steps.branch_names.outputs.staging_branch }}
cmd=$(cat frontend/src/commands.json | jq -r ".redis.user.commit")
eval "$cmd"
# Push through Git, not the CLI, so the exit doesn't break the workflow.
cmd=$(cat frontend/src/commands.json | jq -r ".redis.test.push")
eval "$cmd"
- name: "[add_service] 2. Test: The add_service activity should complete."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.staging_branch }} push state complete "add_service"
- name: "[add_service] 3. Test: The add_service activity should succeed."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.staging_branch }} push result success "add_service"
- name: "[add_service_resources] 4. Test: Test responses on demo app using Blackfire Player."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
URL=$(symfony upsun url --primary --pipe)
sleep $SLEEP
blackfire-player run blackfire.yaml --endpoint="$URL" --variable step=merge-production -vvv
################################################################################################
# H. Promote revision to production.
- name: "[merge] 1. Merge staging into production."
working-directory: ${{ env.PROJECT_LOCALDIR }}
continue-on-error: true
run: |
export STAGING_BRANCH=${{ steps.branch_names.outputs.staging_branch }}
cmd=$(cat frontend/src/commands.json | jq -r ".merge_production.test.merge")
eval "$cmd"
- name: "[merge] 2. Test: The merge activity should complete."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.default_branch }} environment.merge state complete "merge"
- name: "[merge] 3. Test: The merge activity should succeed."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.default_branch }} environment.merge result success "merge"
################################################################################################
# I. Define production service post_merge resources.
- name: "[prod_service_resources] 1. Set Redis' resources on production."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
export DEFAULT_BRANCH=${{ steps.branch_names.outputs.default_branch }}
cmd=$(cat frontend/src/commands.json | jq -r ".merge_production.test.resources_set")
eval "$cmd"
- name: "[prod_service_resources] 2. Test: The update environment resources activity should complete."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.default_branch }} environment.resources.update state complete "init_resources"
- name: "[prod_service_resources] 3. Test: The update environment resources activity should succeed."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.default_branch }} environment.resources.update result success "init_resources"
- name: "[prod_service_resources] 4. Test: Test responses on demo app using Blackfire Player."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
git checkout ${{ steps.branch_names.outputs.default_branch }}
git branch
URL=$(symfony upsun url -e ${{ steps.branch_names.outputs.default_branch }} --primary --pipe)
sleep $SLEEP
blackfire-player run blackfire.yaml --endpoint="$URL" --variable step=complete -vvv
################################################################################################
# J. Scale down to minimum resources
- name: "[scale] 1. Scale down to minimum resources for Redis"
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
export DEFAULT_BRANCH=${{ steps.branch_names.outputs.default_branch }}
cmd=$(cat frontend/src/commands.json | jq -r ".scale.test.resources_set")
eval "$cmd"
- name: "[scale] 2. Test: The update environment resources activity should complete."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.default_branch }} environment.resources.update state complete "init_resources"
- name: "[scale] 3. Test: The update environment resources activity should succeed."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.default_branch }} environment.resources.update result success "init_resources"
- name: "[scale] 4. Test: Test responses on demo app using Blackfire Player."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
git checkout ${{ steps.branch_names.outputs.default_branch }}
git branch
URL=$(symfony upsun url -e ${{ steps.branch_names.outputs.default_branch }} --primary --pipe)
sleep $SLEEP
blackfire-player run blackfire.yaml --endpoint="$URL" --variable step=scale -vvv
################################################################################################
# K. Clean up test project.
- name: "[cleanup] 1. Delete project."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
# upsun project:delete -y
cmd=$(cat frontend/src/commands.json | jq -r ".complete.user.delete_project")
eval "$cmd -y"