diff --git a/.ddev/config.yaml b/.ddev/config.yaml new file mode 100644 index 0000000..2248d72 --- /dev/null +++ b/.ddev/config.yaml @@ -0,0 +1,280 @@ +name: github-runner +type: php +docroot: tests/docroot +php_version: "8.2" +webserver_type: nginx-fpm +xdebug_enabled: false +additional_hostnames: [] +additional_fqdns: [] +database: + type: mariadb + version: "10.11" +use_dns_when_possible: true +composer_version: "2" +web_environment: [] +corepack_enable: false + +# Key features of DDEV's config.yaml: + +# name: # Name of the project, automatically provides +# http://projectname.ddev.site and https://projectname.ddev.site + +# type: # backdrop, craftcms, django4, drupal, drupal6, drupal7, laravel, magento, magento2, php, python, shopware6, silverstripe, typo3, wordpress +# See https://ddev.readthedocs.io/en/stable/users/quickstart/ for more +# information on the different project types +# "drupal" covers recent Drupal 8+ + +# docroot: # Relative path to the directory containing index.php. + +# php_version: "8.2" # PHP version to use, "5.6", "7.0", "7.1", "7.2", "7.3", "7.4", "8.0", "8.1", "8.2", "8.3" + +# You can explicitly specify the webimage but this +# is not recommended, as the images are often closely tied to DDEV's' behavior, +# so this can break upgrades. + +# webimage: # nginx/php docker image. + +# database: +# type: # mysql, mariadb, postgres +# version: # database version, like "10.11" or "8.0" +# MariaDB versions can be 5.5-10.8 and 10.11, MySQL versions can be 5.5-8.0 +# PostgreSQL versions can be 9-16. + +# router_http_port: # Port to be used for http (defaults to global configuration, usually 80) +# router_https_port: # Port for https (defaults to global configuration, usually 443) + +# xdebug_enabled: false # Set to true to enable Xdebug and "ddev start" or "ddev restart" +# Note that for most people the commands +# "ddev xdebug" to enable Xdebug and "ddev xdebug off" to disable it work better, +# as leaving Xdebug enabled all the time is a big performance hit. + +# xhprof_enabled: false # Set to true to enable Xhprof and "ddev start" or "ddev restart" +# Note that for most people the commands +# "ddev xhprof" to enable Xhprof and "ddev xhprof off" to disable it work better, +# as leaving Xhprof enabled all the time is a big performance hit. + +# webserver_type: nginx-fpm, apache-fpm, or nginx-gunicorn + +# timezone: Europe/Berlin +# This is the timezone used in the containers and by PHP; +# it can be set to any valid timezone, +# see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones +# For example Europe/Dublin or MST7MDT + +# composer_root: +# Relative path to the Composer root directory from the project root. This is +# the directory which contains the composer.json and where all Composer related +# commands are executed. + +# composer_version: "2" +# You can set it to "" or "2" (default) for Composer v2 or "1" for Composer v1 +# to use the latest major version available at the time your container is built. +# It is also possible to use each other Composer version channel. This includes: +# - 2.2 (latest Composer LTS version) +# - stable +# - preview +# - snapshot +# Alternatively, an explicit Composer version may be specified, for example "2.2.18". +# To reinstall Composer after the image was built, run "ddev debug refresh". + +# nodejs_version: "20" +# change from the default system Node.js version to any other version. +# Numeric version numbers can be complete (i.e. 18.15.0) or +# incomplete (18, 17.2, 16). 'lts' and 'latest' can be used as well along with +# other named releases. +# see https://www.npmjs.com/package/n#specifying-nodejs-versions +# Note that you can continue using 'ddev nvm' or nvm inside the web container +# to change the project's installed node version if you need to. + +# corepack_enable: false +# Change to 'true' to 'corepack enable' and gain access to latest versions of yarn/pnpm + +# additional_hostnames: +# - somename +# - someothername +# would provide http and https URLs for "somename.ddev.site" +# and "someothername.ddev.site". + +# additional_fqdns: +# - example.com +# - sub1.example.com +# would provide http and https URLs for "example.com" and "sub1.example.com" +# Please take care with this because it can cause great confusion. + +# upload_dirs: "custom/upload/dir" +# +# upload_dirs: +# - custom/upload/dir +# - ../private +# +# would set the destination paths for ddev import-files to /custom/upload/dir +# When Mutagen is enabled this path is bind-mounted so that all the files +# in the upload_dirs don't have to be synced into Mutagen. + +# disable_upload_dirs_warning: false +# If true, turns off the normal warning that says +# "You have Mutagen enabled and your 'php' project type doesn't have upload_dirs set" + +# ddev_version_constraint: "" +# Example: +# ddev_version_constraint: ">= 1.22.4" +# This will enforce that the running ddev version is within this constraint. +# See https://github.com/Masterminds/semver#checking-version-constraints for +# supported constraint formats + +# working_dir: +# web: /var/www/html +# db: /home +# would set the default working directory for the web and db services. +# These values specify the destination directory for ddev ssh and the +# directory in which commands passed into ddev exec are run. + +# omit_containers: [db, ddev-ssh-agent] +# Currently only these containers are supported. Some containers can also be +# omitted globally in the ~/.ddev/global_config.yaml. Note that if you omit +# the "db" container, several standard features of DDEV that access the +# database container will be unusable. In the global configuration it is also +# possible to omit ddev-router, but not here. + +# performance_mode: "global" +# DDEV offers performance optimization strategies to improve the filesystem +# performance depending on your host system. Should be configured globally. +# +# If set, will override the global config. Possible values are: +# - "global": uses the value from the global config. +# - "none": disables performance optimization for this project. +# - "mutagen": enables Mutagen for this project. +# - "nfs": enables NFS for this project. +# +# See https://ddev.readthedocs.io/en/stable/users/install/performance/#nfs +# See https://ddev.readthedocs.io/en/stable/users/install/performance/#mutagen + +# fail_on_hook_fail: False +# Decide whether 'ddev start' should be interrupted by a failing hook + +# host_https_port: "59002" +# The host port binding for https can be explicitly specified. It is +# dynamic unless otherwise specified. +# This is not used by most people, most people use the *router* instead +# of the localhost port. + +# host_webserver_port: "59001" +# The host port binding for the ddev-webserver can be explicitly specified. It is +# dynamic unless otherwise specified. +# This is not used by most people, most people use the *router* instead +# of the localhost port. + +# host_db_port: "59002" +# The host port binding for the ddev-dbserver can be explicitly specified. It is dynamic +# unless explicitly specified. + +# mailpit_http_port: "8025" +# mailpit_https_port: "8026" +# The Mailpit ports can be changed from the default 8025 and 8026 + +# host_mailpit_port: "8025" +# The mailpit port is not normally bound on the host at all, instead being routed +# through ddev-router, but it can be bound directly to localhost if specified here. + +# webimage_extra_packages: [php7.4-tidy, php-bcmath] +# Extra Debian packages that are needed in the webimage can be added here + +# dbimage_extra_packages: [telnet,netcat] +# Extra Debian packages that are needed in the dbimage can be added here + +# use_dns_when_possible: true +# If the host has internet access and the domain configured can +# successfully be looked up, DNS will be used for hostname resolution +# instead of editing /etc/hosts +# Defaults to true + +# project_tld: ddev.site +# The top-level domain used for project URLs +# The default "ddev.site" allows DNS lookup via a wildcard +# If you prefer you can change this to "ddev.local" to preserve +# pre-v1.9 behavior. + +# ngrok_args: --basic-auth username:pass1234 +# Provide extra flags to the "ngrok http" command, see +# https://ngrok.com/docs/ngrok-agent/config or run "ngrok http -h" + +# disable_settings_management: false +# If true, DDEV will not create CMS-specific settings files like +# Drupal's settings.php/settings.ddev.php or TYPO3's AdditionalConfiguration.php +# In this case the user must provide all such settings. + +# You can inject environment variables into the web container with: +# web_environment: +# - SOMEENV=somevalue +# - SOMEOTHERENV=someothervalue + +# no_project_mount: false +# (Experimental) If true, DDEV will not mount the project into the web container; +# the user is responsible for mounting it manually or via a script. +# This is to enable experimentation with alternate file mounting strategies. +# For advanced users only! + +# bind_all_interfaces: false +# If true, host ports will be bound on all network interfaces, +# not the localhost interface only. This means that ports +# will be available on the local network if the host firewall +# allows it. + +# default_container_timeout: 120 +# The default time that DDEV waits for all containers to become ready can be increased from +# the default 120. This helps in importing huge databases, for example. + +#web_extra_exposed_ports: +#- name: nodejs +# container_port: 3000 +# http_port: 2999 +# https_port: 3000 +#- name: something +# container_port: 4000 +# https_port: 4000 +# http_port: 3999 +# Allows a set of extra ports to be exposed via ddev-router +# Fill in all three fields even if you don’t intend to use the https_port! +# If you don’t add https_port, then it defaults to 0 and ddev-router will fail to start. +# +# The port behavior on the ddev-webserver must be arranged separately, for example +# using web_extra_daemons. +# For example, with a web app on port 3000 inside the container, this config would +# expose that web app on https://.ddev.site:9999 and http://.ddev.site:9998 +# web_extra_exposed_ports: +# - name: myapp +# container_port: 3000 +# http_port: 9998 +# https_port: 9999 + +#web_extra_daemons: +#- name: "http-1" +# command: "/var/www/html/node_modules/.bin/http-server -p 3000" +# directory: /var/www/html +#- name: "http-2" +# command: "/var/www/html/node_modules/.bin/http-server /var/www/html/sub -p 3000" +# directory: /var/www/html + +# override_config: false +# By default, config.*.yaml files are *merged* into the configuration +# But this means that some things can't be overridden +# For example, if you have 'use_dns_when_possible: true'' you can't override it with a merge +# and you can't erase existing hooks or all environment variables. +# However, with "override_config: true" in a particular config.*.yaml file, +# 'use_dns_when_possible: false' can override the existing values, and +# hooks: +# post-start: [] +# or +# web_environment: [] +# or +# additional_hostnames: [] +# can have their intended affect. 'override_config' affects only behavior of the +# config.*.yaml file it exists in. + +# Many DDEV commands can be extended to run tasks before or after the +# DDEV command is executed, for example "post-start", "post-import-db", +# "pre-composer", "post-composer" +# See https://ddev.readthedocs.io/en/stable/users/extend/custom-commands/ for more +# information on the commands that can be extended and the tasks you can define +# for them. Example: +#hooks: diff --git a/.github/workflows/operations.site.command.yml b/.github/workflows/operations.site.command.yml new file mode 100644 index 0000000..f8755a6 --- /dev/null +++ b/.github/workflows/operations.site.command.yml @@ -0,0 +1,45 @@ +# +# Site Command. Use to run any command. +# +name: Run command +on: + workflow_call: + inputs: + + working_directory: + required: true + type: string + description: The path to run the command in. + + command: + type: string + description: The command to run. + required: true + + github_runs_on: + type: string + default: ubuntu-latest + description: The label of the runner you wish to use. + + env: + type: string + description: | + A string of environment variables to set for the command run. To alter the summary, see https://github.com/jonpugh/goatscripts/blob/main/src/run-with-summary + +jobs: + run-command: + name: Run command + runs-on: ${{ inputs.github_runs_on }} + steps: + - uses: jonpugh/goatscripts@main + + - name: run command + env: + SUCCESS: ":white_check_mark: Command complete" + ERROR: ":x: Command failed" + SUMMARY: | + - Root: `${{ inputs.working_directory }}` + working-directory: ${{ inputs.working_directory }} + run: | + ${{ inputs.env }} + run-with-summary ${{ inputs.command }} diff --git a/.github/workflows/operations.site.deploy.ddev.yml b/.github/workflows/operations.site.deploy.ddev.yml new file mode 100644 index 0000000..96e3860 --- /dev/null +++ b/.github/workflows/operations.site.deploy.ddev.yml @@ -0,0 +1,269 @@ +# +# Operations Project Workflow: Deploy DDEV Site. +# +# This reusable workflow will deploy a website with DDEV. +# +# See https://github.com/operations-project/github-action-ddev-runner for more information. +# +name: Deploy site +on: + workflow_call: + + secrets: + SSH_PRIVATE_KEY: + description: A private key to use to clone repositories and, optionally, to sync data. + required: false + + inputs: + + git_repository: + default: ${{ github.event.repository.ssh_url }} + type: string + description: The repository to deploy. + + git_reference: + default: ${{ github.head_ref || github.ref_name }} + type: string + description: The git reference to deploy. + + git_root: + required: true + type: string + description: The path to clone the repository into, relative to the runner workspace. Use absolute paths when running a persistent server. + + start_command: + default: ddev start + type: string + description: The command to launch the site servers. + + run_start_command: + default: true + type: boolean + description: Whether to run the ddev start command. + + # AKA Sync or Install. + prepare_command: + default: ddev drush site:install + type: string + description: The command to run to prepare site data, such as a sync script, migration or install profile. + + run_prepare_command: + # False by default to prevent data loss. If there is no data, the prepare command will still be run. + default: false + type: boolean + description: Whether to run the prepare command. + + deploy_command: + default: ddev drush deploy + type: string + description: The command to run after deploying new code. + + run_deploy_command: + default: true + type: boolean + description: Whether to run the deploy command. + + ddev_project_name: + type: string + default: ${{ github.event.repository.name }} + description: The ddev project name for this environment. Must be unique on this server. Will be used for the default domain using {ddev_project_name}.{ddev_project_tld}. + + ddev_project_tld: + type: string + description: The top-level domain used for the environment. + + ddev_config: + type: string + description: Extra ddev configuration for this environment to write to .ddev/config.zzz.workflow.yaml. Use to apply environment-specific configuration, additional_fqdns, etc. + + ddev_config_filename: + default: "config.zzz.hosting.yaml" + type: string + description: The file to create in the .ddev folder to store the ddev configuration. + + github_runs_on: + type: string + default: ubuntu-latest + description: The label of the runner you wish to use. + + github_environment_name: + type: string + default: ${{ github.head_ref || github.ref_name }} + description: The string to use as the GitHub environment. + + github_environment_url: + type: string + default: ${{ inputs.ddev_project_name }}.${{ inputs.ddev_project_tld }} + description: The URL to use for the GitHub environment. + +env: + # Tell ddev to not set /etc/hosts file. + DDEV_NONINTERACTIVE: true + + # Tell run-with-summary to skip the details table. + HIDE: true + + # Start an SSH agent with this private key. + SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + +jobs: + deploy-code: + name: Deploy Code + runs-on: ${{ inputs.github_runs_on }} + env: + SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + + steps: + + - name: Show environment + run: env + + - name: Install scripts + uses: jonpugh/goatscripts@main + + # Enable SSH agent to allow preview sites to clone. + - uses: webfactory/ssh-agent@v0.9.1 + if: ${{ env.SSH_PRIVATE_KEY }} + with: + ssh-private-key: ${{ env.SSH_PRIVATE_KEY }} + + - name: Clone code + env: + SUCCESS: "Codebase successfully cloned :computer:" + ERROR: "Git clone failed :x:" + SUMMARY: | + - Repository: ${{ inputs.git_repository }} + - Reference: ${{ inputs.git_reference }} + - Root: ${{ inputs.git_root }} + - Environment: ${{ inputs.github_environment_name }} + - URL: ${{ inputs.github_environment_url }} + - Pull Request: ${{ github.event.pull_request.html_url }} + + run: | + if [[ ! -d ${{ inputs.git_root }} ]]; then + run-with-summary git clone --recursive ${{ inputs.git_repository }} ${{ inputs.git_root }} + fi + cd ${{ inputs.git_root }} + git checkout --force ${{ inputs.git_ref }} + git submodule sync --recursive + + SUMMARY="" + + SUCCESS="Pre-deploy git status" \ + run-with-summary git log -1 + + git fetch + git checkout ${{ inputs.git_reference }} + git reset --hard origin/${{ inputs.git_reference }} + + SUCCESS="Post deploy git status" \ + run-with-summary git log -1 + + SUCCESS="git status" \ + run-with-summary git status + + start-site: + name: Start site + runs-on: ${{ inputs.github_runs_on }} + needs: deploy-code + + # Show links to this environment in the UI to the site. + environment: + name: ${{ inputs.github_environment_name }} + url: "${{ inputs.github_environment_url }}" + + steps: + + - name: Install helper scripts + uses: jonpugh/goatscripts@v1 + + - name: Check DDEV Installation + run: | + if [[ `command -v ddev` ]]; then + echo "DDEV is already installed." + echo "DDEV_INSTALLED=true" >> $GITHUB_ENV + else + echo "DDEV is not installed." + echo "DDEV_INSTALLED=false" >> $GITHUB_ENV + fi + + if [[ `sudo pwd` ]]; then + echo "Runner has sudo access." + echo "RUNNER_SUDO=true" >> $GITHUB_ENV + else + echo "Runner does not have sudo access." + echo "RUNNER_SUDO=false" >> $GITHUB_ENV + fi + + if [[ $DDEV_INSTALLED == "false" && $RUNNER_SUDO == "false" ]]; then + echo "Unable to continue. DDEV cannot be installed without sudo access." + exit 1 + fi + + # Install DDEV, if needed. + # This only works for runners by sudo users. Don't run it if ddev is already installed. + - name: Setup DDEV + uses: ddev/github-action-setup-ddev@v1 + if: ${{ env.DDEV_INSTALLED == 'false' }} + with: + autostart: false + + - name: Configure DDEV + working-directory: ${{ inputs.git_root }}/.ddev + run: | + ddev config global --instrumentation-opt-in=false + echo "# DDEV Config created by GitHub workflow https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" > ${{ inputs.ddev_config_filename }} + echo "name: ${{ inputs.ddev_project_name }}" >> ${{ inputs.ddev_config_filename }} + echo "project_tld: ${{ inputs.ddev_project_tld }}" >> ${{ inputs.ddev_config_filename }} + echo "${{ inputs.ddev_config }}" >> ${{ inputs.ddev_config_filename }} + + - name: Install scripts + uses: jonpugh/goatscripts@main + + - name: Start site + working-directory: ${{ inputs.git_root }} + if: ${{ inputs.run_start_command }} + env: + SUCCESS: "Started DDEV Site :rocket:" + ERROR: "DDEV start failed :x:" + run: | + run-with-summary ${{ inputs.start_command }} + + # Import, sync, install, etc. + prepare-data: + name: Prepare data + runs-on: ${{ inputs.github_runs_on }} + needs: start-site + if: ${{ inputs.run_prepare_command && inputs.prepare_command}} + + # Show links to this environment in the UI to the site. + environment: + name: ${{ inputs.github_environment_name }} + url: "${{ inputs.github_environment_url }}" + + steps: + + - name: Install scripts + uses: jonpugh/goatscripts@main + + # Enable SSH agent. + - uses: webfactory/ssh-agent@v0.9.1 + if: ${{ inputs.SSH_PRIVATE_KEY }} + with: + ssh-private-key: ${{ inputs.SSH_PRIVATE_KEY }} + + - name: Prepare data + working-directory: ${{ inputs.git_root }} + env: + SUCCESS: "Site data preparation successful :rocket:" + ERROR: "Site data preparation failed :x:" + run: | + run-with-summary ${{ inputs.prepare_command }} + + - name: Deploy command + working-directory: ${{ inputs.git_root }} + env: + SUCCESS: "Deploy successful :rocket:" + ERROR: "Deploy failed :x:" + run: | + run-with-summary ${{ inputs.deploy_command }} diff --git a/.github/workflows/operations.site.destroy.ddev.yml b/.github/workflows/operations.site.destroy.ddev.yml new file mode 100644 index 0000000..683356f --- /dev/null +++ b/.github/workflows/operations.site.destroy.ddev.yml @@ -0,0 +1,81 @@ +# +# Operations Project Workflow: Destroy DDEV Site. +# +# This reusable workflow will DESTROY a DDEV hosted website. +# +# See https://github.com/operations-project/github-action-ddev-runner for more information. +# +name: Destroy site +on: + workflow_call: + inputs: + + git_root: + required: true + type: string + description: The path to the existing DDEV site. + + destroy_command: + default: ddev remove --remove-data --omit-snapshot + type: string + description: The command to destroy the site and codebase. + + remove_code: + default: true + type: boolean + description: Whether to remove the codebase. + + github_runs_on: + type: string + default: ubuntu-latest + description: The label of the runner you wish to use. + +jobs: + destroy-site: + name: Destroy site + runs-on: ${{ inputs.github_runs_on }} + steps: + + - uses: actions/checkout@v4 + with: + repository: 'jonpugh/goatscripts' + ref: 'v1.1.0' + path: goatscripts + + - name: Set environment + run: | + echo "$GITHUB_WORKSPACE/goatscripts/src" >> $GITHUB_PATH + echo ${{ inputs.git_root }} + ls -la ${{ inputs.git_root }} + + - name: Destroy site + working-directory: ${{ inputs.git_root }} + env: + SUCCESS: "DDEV site removed :check_mark:" + ERROR: "Unable to remove DDEV site :x:" + run: | + run-with-summary ${{ inputs.destroy_command }} + + destroy-code: + name: Destroy Code + runs-on: ${{ inputs.github_runs_on }} + needs: destroy-site + steps: + - uses: actions/checkout@v4 + with: + repository: 'jonpugh/goatscripts' + ref: 'v1.1.0' + path: goatscripts + + - name: Set environment + run: echo "$GITHUB_WORKSPACE/goatscripts/src" >> $GITHUB_PATH + + - name: Remove code + env: + SUCCESS: "Codebase removed :check_mark:" + ERROR: "Unable to remove codebase :x:" + SUMMARY: | + - Root: ${{ inputs.git_root }} + run: | + run-with-summary rm -rf ${{ inputs.git_root }} + diff --git a/.github/workflows/site.preview.yml.example b/.github/workflows/site.preview.yml.example new file mode 100644 index 0000000..e90c831 --- /dev/null +++ b/.github/workflows/site.preview.yml.example @@ -0,0 +1,81 @@ +# +# site.preview.yml +# +# Launch and test preview sites for each pull request. +# +# Requires a runner on a persistant server. +# +name: Preview Site +on: + pull_request: + +# Cancel jobs if another push is received. +concurrency: + group: ${{ github.workflow }}-${{ github.event.number }} + cancel-in-progress: false + +jobs: + + # Installs DDEV, clones code, starts the site. + create-site: + name: Create Preview Site + uses: operations-project/github-action-ddev-runner/.github/workflows/operations.site.deploy.ddev.yml@feature/reusable-workflows + with: + + # Where to install your site. + git_root: /home/runner/Sites/${{ github.repository }}/pr${{ github.event.number }} + + # Project name for this instance. Used to generate the domain name. + ddev_project_name: yourproject.pr${{ github.event.number }} + + # Top-level domain. Sites are hosted as subdomains under this. + ddev_project_tld: preview.yourproject.com + + # Tell the remote workflow what to run on. + github_runs_on: self-hosted + + # Define the github environment name, to be displayed in the UI. + github_environment_name: pr${{ github.event.number }} + + # Define a github environment url, a link to be shown on the pull request. + github_environment_url: http://yourproject.pr${{ github.event.number }}.preview.yourproject.com + + # To persist a site's data, set "run_prepare_command" to false. + run_prepare_command: true + + # Prepare the site's data. Run your sync/import/install script. + prepare_command: ddev drush site:install + + # Command to run after deploying code changes + deploy_command: ddev drush updb + + # Additional ddev config to apply to the environment. + # Will be saved to .ddev/config.zzz.runner.yaml + # See your project's .ddev/config.yaml file for examples. + ddev_config: | + additional_fqdns: + - admin.pr${{ github.event.number }}.preview.yourproject.com + + run-command: + name: DDEV Status + uses: operations-project/github-action-ddev-runner/.github/workflows/operations.site.command.yml@feature/reusable-workflows + needs: create-site + with: + working_directory: /home/runner/Sites/${{ github.repository }}/pr${{ github.event.number }} + github_runs_on: self-hosted + command: | + ddev status + + test-site: + name: Run tests + needs: run-command + runs-on: self-hosted + steps: + - uses: jonpugh/goatscripts@main + - name: Check homepage + env: + SUCCESS: "Tests pass. :check:" + ERROR: "TESTS FAILED! :x:" + run: | + run-with-summary curl http://pr${{ github.event.number }}.sites.thinkdrop.net + curl -s http://yourproject.pr${{ github.event.number }}.preview.yourproject.com | grep "Hello World!" diff --git a/.github/workflows/test.ddev.workflows.yml b/.github/workflows/test.ddev.workflows.yml new file mode 100644 index 0000000..9a44b4a --- /dev/null +++ b/.github/workflows/test.ddev.workflows.yml @@ -0,0 +1,122 @@ +# +# This workflow is for testing the re-usable ones workflows. +# +# It contains multiple steps, including starting and tearing down a site. +# It doesn't make sense to use this example directly. +# +# See the example.* files for that. +# +name: Preview Sites +on: + pull_request: + +env: + # This example creates github runners for each subsequent job. + # To do so, it needs a GitHub token with admin:write permissions. + # Create a personal access token with admin:write permissions on the repository you wish to deploy. + GITHUB_TOKEN: "${{ secrets.OPERATIONS_GITHUB_TOKEN_ADMIN }}" + +concurrency: + group: ${{ github.workflow }}-${{ github.event.number }} + cancel-in-progress: false + +jobs: + # This emulates a persistent server. The ddev.site.deploy.yml jobs require one. + # This job runs the rest. It will stay running until the last job is complete. + create-server: + name: Launch test runner + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + repository: 'operations-project/github-runner-starter' + ref: 'v1.2.1' + + # Kick off the runner script over and over until there are no more queued jobs. + - name: "Launch runner script." + + run: | + while [[ $(curl -s -H "Authorization: token ${GITHUB_TOKEN}" "https://api.github.com/repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/jobs" | jq -r '.jobs[] | select(.status=="queued") | .id' | wc -l) -gt 0 ]]; do + sleep 2 + ./github-runner-starter \ + --run \ + --name=github.actions.runner.${{ github.run_id }}.${{ matrix.runner }} \ + --labels=github.actions.runner.${{ github.run_id }} \ + --config-sh-options=--ephemeral + sleep 2 + done + + create-site: + name: Create Preview Site + uses: operations-project/github-action-ddev-runner/.github/workflows/operations.site.deploy.ddev.yml@feature/reusable-workflows + with: + + # Configure your site here. + git_root: /home/runner/ourproject/pr${{ github.event.number }} + + # Use the http URL. + git_repository: ${{ github.event.repository.clone_url }} + + # Must be unique per server. + ddev_project_name: ourproject.pr${{ github.event.number }} + + # Used to create a system domain. + ddev_project_tld: sites.thinkdrop.net + + # Tell the remote workflow what to run on. + github_runs_on: github.actions.runner.${{ github.run_id }} + + # Define the github environment name, to be displayed in the UI. + github_environment_name: pr${{ github.event.number }} + + # Define a github environment url, a link to be shown on the pull request. + github_environment_url: http://pr${{ github.event.number }}.sites.thinkdrop.net + + # To persist a site's data, set "run_prepare_command" to false. + run_prepare_command: true + prepare_command: echo "Preparing site..." + + # Command to run after deploying code. + deploy_command: ddev exec echo "Hello from $(hostname)!" + + # Additional ddev config to apply to the environment. + # Will be saved to .ddev/config.zzz.runner.yaml + ddev_config: | + additional_fqdns: + - admin.pr${{ github.event.number }}.sites.thinkdrop.net + - ddev-runner.ddev.site + + run-command: + name: DDEV Status + uses: operations-project/github-action-ddev-runner/.github/workflows/operations.site.command.yml@feature/reusable-workflows + needs: create-site + with: + working_directory: /home/runner/ourproject/pr${{ github.event.number }} + github_runs_on: github.actions.runner.${{ github.run_id }} + command: ddev status + env: | + SUCCESS="DDEV Status" + HIDE=1 + + test-site: + name: Run tests + needs: create-site + runs-on: github.actions.runner.${{ github.run_id }} + steps: + + - uses: jonpugh/goatscripts@main + - name: Check homepage for Hello World. + env: + SUCCESS: "Tests passed! DDEV webserver is online. :boom:" + ERROR: "Unable to load DDEV website. :x:" + run: | + run-with-summary curl https://ddev-runner.ddev.site + curl -s https://ddev-runner.ddev.site | grep "Hello World!" + + remove-site: + name: Remove Site + uses: operations-project/github-action-ddev-runner/.github/workflows/operations.site.destroy.ddev.yml@feature/reusable-workflows + needs: test-site + with: + git_root: /home/runner/ourproject/pr${{ github.event.number }} + github_runs_on: github.actions.runner.${{ github.run_id }} diff --git a/README.md b/README.md index 4bdb238..09a1866 100644 --- a/README.md +++ b/README.md @@ -1,75 +1,44 @@ -# DDEV GitHub Actions Runner +# DDEV Hosting Reusable GitHub Actions +## Self-hosted automation for ddev projects -This GitHub Action is designed to host real live sites using self-hosted GitHub runners and DDEV. +These reusable GitHub Workflows allow you to automate the deployment and testing of DDEV sites on your own servers. -DDEV is a tool for launching multiple sites on a single server using Docker. +Useful for hosting and CI/CD servers. -This action makes it easy to clone a site and launch `ddev start`. +## Reusable Workflows -For more detailed documentation and usage examples, see https://operations-project.gitbook.io/operations-experience-project/operations-site-server. +Include these workflows inside your own github workflow files: -Notes ------ - -This action does NOT install `ddev`. +- [`operations.site.deploy.yml`](./.github/workflows/operations.site.deploy.ddev.yml) + - **Deploy Code:** git clone and checkout desired branch to desired path. + - **Start Site:** Write special DDEV configs and run `ddev start` to launch the site. + - **Import Site:** Run your own sync command to import or install your site. +- [`operations.site.destroy.yml`](./.github/workflows/operations.site.destroy.ddev.yml) + - **Remove Site**: `ddev rm -OR` + - **Remove Code**: `rm -rf $DIR` +- More workflows TBD. -If using on a self-hosted runner, make sure you install ddev first. +## Server Setup -If running in CI, you can install DDEV in github workflows with this action: https://github.com/Lullabot/drainpipe/blob/main/scaffold/github/actions/common/ddev/action.yml +To prepare a server for running these workflows, you can use the [Operations Site Runner]([url](https://github.com/operations-project/ansible-collection-site-runner)) Ansible collection. see https://github.com/operations-project/ansible-collection-site-runner. -Operations Site Runner ----------------------- +The main components: -You can prepare a server for running sites using the Operations Site Runner tool: https://github.com/operations-project/site-runner/ - -It will prepare server users, install DDEV, and setup GitHub Runners as a service. +- Sysadmin users from GitHub accounts. +- Platform user for running sites. +- Control (sudo) user for configuring server. +- Docker +- DDEV +- GitHub runners, one per repository. Usage ----- -Copy the example workflows located at [examples/.github/workflows](./examples/.github/workflows) to your projects `.github/workflows` folder. - -The workflows allow all tasks that need to run against your site to be logged in GitHub actions. - -- [deploy.yml](./examples/.github/workflows/deploy.yml) - Deploys fixed sites like live/test/dev when specific branches are pushed. -- [pull-request.yml](./examples/.github/workflows/pull-request.yml) - Deploys pull request environments. -- [pull-request-closed.yml](./examples/.github/workflows/pull-request-closed.yml) - Removes pull request environments. -- [cron.yml](./examples/.github/workflows/cron.yml) - Runs Drupal crontab as a scheduled workflow. +Copy the `example.*.yml` workflows located at [.github/workflows/](.github/workflows) to your projects `.github/workflows` folder. Pull Requests and Live Environments must be handled in separate files, so that live sites only deploy on specific branches. -```yaml -# ./.github/workflows/pull-requests.yml -name: Pull Requests -on: [pull_request] -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: operations-project/site-runner-ddev@main - with: - # Set to "yes" to run the "sync-command". THIS WILL DESTROY THE SITE DATA. - sync: "yes" - - # The command to run to sync up the site with data. - # The default (shown) assumes you have a drush alias of @live. - sync-command: "ddev drush sql:sync @live @self" - - # Add SSH information to GitHub secrets to connect to remote servers. - # Command to get SSH_KNOWN_HOSTS: - # ssh-keyscan -H yourliveserver.com -H github.com - ssh-known-hosts: ${{ secrets.SSH_KNOWN_HOSTS }} - - # Put a private key in secrets and in the live sites `.ssh/authorized_keys` file. - ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} - - # The DDEV `project_tld` config option determines the URLs that are created for the sites. - # You can set the TLD here, or use the GitHub Runner user's global ddev config. - ddev-project-tld: "ci.myserver.com" - - # A list of domains to apply to this environment. Must be a string because of github actions. - ddev-fqdns: | - - preview.${{ github.event.number }}.ci.thinkdrop.net +For a complete example, see [.github/workflows/example.site.preview.yml](.github/workflows/example.site.preview.yml) # ... then your own project steps ... ``` diff --git a/tests/docroot/index.html b/tests/docroot/index.html new file mode 100644 index 0000000..c57eff5 --- /dev/null +++ b/tests/docroot/index.html @@ -0,0 +1 @@ +Hello World! \ No newline at end of file