Skip to content

systemcarl/folio

Repository files navigation

folio

These automation tools contain the code and configuration files for building and deploying the Blank application. The application is built and bundled using the SvelteKit Node.js adapter and the output is containerized into a Docker image.

Prerequisites

To execute the provided scripts, the following dependencies are required:

Environment Variables

All variables can be set in the execution environment, included in a .env file in the root of the repository, or passed as arguments to the scripts — evaluated in that order.

The following environment variables are used during the execution of the scripts:

  • ENVIRONMENT: The environment being deployed. Expected to be either production or staging. Environment state is stored separately in the same Google Cloud Storage bucket.
  • GOOGLE_CREDENTIALS: The path to the Google Cloud Service credentials JSON file. Used by default during deployment operations.
  • FOLIO_APP_DOMAIN: The domain name of the deployed application.
  • FOLIO_CF_DNS_ZONE: The Cloudflare DNS of the domain of the application domain. Used to update the DNS records.
  • FOLIO_SSH_PORT: The configured SSH port the deployed application server.
  • FOLIO_ACME_EMAIL: The email address used to register the Let's Encrypt SSL certificate for the application domain.
  • FOLIO_SSH_KEY_ID: The DigitalOcean identifier of the SSH key used to initialize the application server.
  • FOLIO_PRIVATE_KEY_FILE: The path to the private key file used by the default user of the deployed application server. This private key can be used to access the application server after deployment as user app.
  • FOLIO_PUBLIC_KEY_FILE: The path to the public key file used by the default user of the deployed application server.
  • FOLIO_GCS_CREDENTIALS: The path to the Google Cloud Service credentials JSON file. Overrides the global GOOGLE_CREDENTIALS variable.
  • FOLIO_CF_TOKEN: The Cloudflare API token used to update the DNS records of the application domain. See Deployment for required permission scopes.
  • FOLIO_DO_TOKEN: The DigitalOcean API token used to create and manage the application server. See Deployment for required permission scopes.
  • FOLIO_GH_TOKEN: The GitHub API token used to update the commit status of the application and CI/CD pipeline. See Status for required permission scopes.
  • FOLIO_GHPR_TOKEN: The GitHub API token used to authenticate Docker with the GitHub Packages registry.
  • SENTRY_DSN: The public Sentry DSN used to report errors and performance issues.
  • SENTRY_ORG: The Sentry organization name used to upload source maps during containerization. This environment variable is not deployed with the application.
  • SENTRY_PROJECT: The Sentry project name used to upload source maps during containerization. This environment variable is not deployed with the application.
  • SENTRY_AUTH_TOKEN: The Sentry authentication token used to upload source maps during containerization. This environment variable is not deployed with the application.
  • LOKI_URL: The URL of the external Loki instance to send logs to, from the deployed application.
  • LOKI_USERNAME: The basic auth username for basic authenticating the deployed application with the external Loki instance.
  • LOKI_PASSWORD: The basic auth password for basic authenticating the deployed application with the external Loki instance.

Validation

Before building the application, you can validate the application code using the validate script. This script will run all tests defined in the Blank application.

validate

Build & Containerization

To build and containerize a deployable application, run the provided containerization script. If successful, the script resulting image will be tagged as folio:latest and pushed to the local Docker registry.

containerize

To push to the GitHub Packages registry, option --push can be used. To see the full list of options, run the script with the --help option.

containerize --push

The available Docker engine must be authenticated to the write to the target application package. Alternatively, the FOLIO_GHPR_TOKEN environment variable can be set to a "classic" GitHub API token with the necessary scopes:

  • write:packages When FOLIO_GHPR_TOKEN is set, containerization will automatically attempt to authenticate the available Docker engine to the GitHub Packages registry before any operations are performed.

Deployment

The Blank application can be deployed to a remote server or a local Docker instance for development and testing using the deploy script. To see the full list of options, run the script with the --help option.

deploy --help

Remote Deployment

By default, the script will attempt to deploy the application to a remote server by applying a Terraform plan. Appropriate configuration must be provided; see the script usage for details for more information.

deploy

The configured Cloudflare API token must have the scopes, for all applicable zones:

  • DNS:Edit.

The configured DigitalOcean API token must have the scopes:

  • droplet:create,
  • droplet:read,
  • droplet:update,
  • droplet:delete.
  • reserved_ip:read,
  • reserved_ip:create,
  • reserved_ip:update,
  • reserved_ip:delete.
  • ssh_key:read,
  • tag:read,
  • tag:create,
  • tag:delete

To deploy remotely the target application package must be publicly available on the GitHub Packages registry. If a GitHub Packages API token is used to automatically authenticate Docker, it must have the scopes:

  • read:packages,
  • write:packages.

To automatically apply the Terraform plan without interaction, you can add the --approve option.

deploy --approve

Remote deployment requires that the requested folio Docker image version is available on GitHub Packages.

Staging

To avoid exposing potentially unstable code or hitting rate limits during testing, the --staging option can be used to deploy the application to a staging environment.

deploy --staging

Specifying the --staging option will deploy the application with the staging environment configuration. If a domain is not specified as an argument, the application will be deployed to the staging. subdomain of the configured domain.

When staging, a staging SSL certificate will be issued by Let's Encrypt, instead of a production certificate.

Alternate Environments

Any environment can be deployed by specifying the --environment option with the desired environment name. The --test option can be used as a shorthand for --environment test.

deploy --environment <environment_name>
deploy --test

Unless a domain is specified as an argument, the application will be deployed to the <environment>. subdomain, unless the environment is production. Otherwise, the application will be deployed the same as a staging deployment.

Local Deployment

If the --local option is used, the script will attempt to run the application on a local container, exposing port 3000. The latest image will be pull from the local Docker registry, or if unavailable, the GitHub Packages registry. port 3000.

deploy --local

Cleanup

To tear down the application, either to cleanup local development or destroy the remote resources, the destroy script can be executed. A usage description can be obtained by running the script with the --help option.

destroy --help

Remote Cleanup

To destroy the remote resources, the script requires the same environment configuration as the deploy script. The parameters are required to ensure the correct resources are identified and destroyed by Terraform.

destroy

To automatically apply approve the destruction of all resources, add the --approve option.

destroy --approve

Local Cleanup

To clean up the local resources, the script will attempt to stop and remove the folio container, and remove the local Docker image.

destroy --local

Testing

This deployment project includes a test suite that can be run to ensure all non-application deployment code is functioning as expected.

test

Script unit tests are run using a BATS Docker container that is automatically pulled and executed. Terraform tests are executed using the Terraform CLI. By default, an integration test is performed, deploying the application to a remote server using the test environment configuration.

To target specific test files, you can pass an individual test file or directory as an argument to the test script. Tests can also be filtered by name using the --filter option. Only BATS test files can be narrowed by file or test name.

test <file_or_directory> --filter <test_name>

To isolate a specific test suite — either cli or infrastructure tests — you can use the --cli or --infra options, respectively. Infrastructure tests include both the Terraform and cloud-init script tests. Terraform tests can be run in isolation using the --terraform option. A test deployment can be performed without running the full test suite using the --deploy option.

test --cli
test --infra
test --terraform
test --deploy

Code Status

The commit status of both the Blank application and the folio CI/CD pipeline can be retrieved from GitHub. By default, the status script retrieves the current version of the Blank application. Alternatively, a branch, tag, or commit SHA as an argument to the script. To target the folio CI/CD pipeline, the --self option can be used.

status [<application_commit>]
status --self [<pipeline_commit>]

The commit status can be set manually using the set subcommand. The subcommand requires a status argument, which can be one of success, failure, or pending. Optionally, the target commit can be specified before the status argument.

status set [<application_commit>] <status>
status set --self [<pipeline_commit>] <status>

The configured GitHub API token must have the scopes:

  • commit_status:read,
  • commit_status:write,
  • contents:read

Process Status

Some commands will automatically set the commit statuses of the blank application and the folio CI/CD pipeline when given the --set-status option.

deploy --set-status
validate --set-status
test --set-status

This is used by default during (automation)[#automation] to reduce the likelihood of redundant pipeline runs. To force a command to run, even if the commit status is already set, the --force option can be used.

deploy --set-status --force
validate --set-status --force
test --set-status --force

Automation

While local testing and deployment is more reliable, common tasks can be automated via GitHub Actions. The application can be validated, deployed, and destroyed using the provided workflows. Additionally, the CI/CD pipeline includes testing workflows that checks the integrity of the GitHub Actions environment and configuration, and test all CI/CD pipeline scripts.

The workflows wrap their corresponding CLI commands:

  • "Deploy Application" — deploy,
  • "Teardown Application" — destroy,
  • "Validate Application" — validate,
  • "Test Application" — test.

Additionally, the "Verify CI/CD Configuration" workflow checks the GitHub Actions environment configuration and performs a dry run integration test of all other workflows.

These workflows can be dispatched manually. The "Deploy Application" workflow is automatically triggered on pushes to the main or staging branches. The "Test Application" and "Verify CI/CD Configuration" workflows are triggered on any update to repository files, not including submodule updates.

Environment Configuration

The GitHub Actions workflows expect the following environments to be configured:

  • production,
  • staging,
  • test,
  • verification.

All environments except verification are used to deploy the application, and require all the necessary environment variables to be set as variables:

  • FOLIO_APP_DOMAIN;

or as secrets:

  • FOLIO_CF_DNS_ZONE,
  • FOLIO_SSH_PORT,
  • FOLIO_ACME_EMAIL,
  • FOLIO_SSH_KEY_ID,
  • FOLIO_PRIVATE_KEY_FILE,
  • FOLIO_PUBLIC_KEY_FILE,
  • FOLIO_GCS_CREDENTIALS,
  • FOLIO_CF_TOKEN,
  • FOLIO_DO_TOKEN,
  • FOLIO_GH_TOKEN,
  • FOLIO_GHPR_TOKEN,
  • SENTRY_DSN,
  • SENTRY_ORG,
  • SENTRY_PROJECT,
  • SENTRY_AUTH_TOKEN,
  • LOKI_URL,
  • LOKI_USERNAME,
  • LOKI_PASSWORD.

For test safety, the verification environment must not have any authentication secrets set:

  • FOLIO_GCS_CREDENTIALS,
  • FOLIO_CF_TOKEN,
  • FOLIO_DO_TOKEN,
  • FOLIO_GH_TOKEN,
  • FOLIO_GHPR_TOKEN,
  • SENTRY_AUTH_TOKEN,
  • LOKI_PASSWORD.

If the application submodule repository is private, an authentication token with read access to the repository must be set as a secret:

  • REPO_TOKEN.

Environment Verification

It is recommended that the GitHub Actions environment is verified via the "Verify CI/CD Configuration" workflow before running any other workflows. Dispatching the "Verify CI/CD Configuration" workflow with the check option of environment will ensure that the environment variables and secrets are set correctly.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published