diff --git a/.github/workflows/deploy-website.yml b/.github/workflows/deploy-website.yml index 8692d12d8..d1860702b 100644 --- a/.github/workflows/deploy-website.yml +++ b/.github/workflows/deploy-website.yml @@ -14,12 +14,6 @@ on: default: 'refs/heads/main' commit: description: 'Commit SHA to deploy from (optional)' - environment: - type: choice - description: 'Environment to deploy to (Default: canary)' - options: - - canary - - prod # Construct a concurrency group to be shared across workflow runs. # The default behavior ensures that only one is running at a time, with @@ -30,9 +24,6 @@ permissions: contents: read id-token: write # Allow the workflow to create a JWT for AWS auth -env: - JOB: spin-docs - jobs: echo-inputs: runs-on: ubuntu-latest @@ -42,103 +33,82 @@ jobs: run: | echo ref: ${{ github.event.inputs.ref }} echo commit: ${{ github.event.inputs.commit }} - echo environment: ${{ github.event.inputs.environment }} deploy: runs-on: ubuntu-latest if: ${{ github.repository_owner == 'fermyon' }} + env: + OCI_IMAGE_NAME: spin-docs steps: - uses: actions/checkout@v3 - - name: Install Nomad - env: - NOMAD_VERSION: "1.4.3" - run: | - curl -Os https://releases.hashicorp.com/nomad/${NOMAD_VERSION}/nomad_${NOMAD_VERSION}_linux_$(dpkg --print-architecture).zip - unzip nomad_${NOMAD_VERSION}_linux_$(dpkg --print-architecture).zip -d /usr/local/bin - chmod +x /usr/local/bin/nomad + - name: Check out specific ref + if: ${{ github.event_name == 'workflow_dispatch' }} && ${{ inputs.ref != ''}} + run: git checkout ${{ inputs.ref }} - # This action currently generates a warning due to using deprecated features. - # https://github.com/aws-actions/configure-aws-credentials/issues/521 tracks the new behaviour. - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v1 - with: - role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.INFRA_NAMESPACE }}-${{ secrets.AWS_REGION }}-gha-certs - role-session-name: fermyon-developer-deploy - aws-region: ${{ secrets.AWS_REGION }} + - name: Check out specific commit + if: ${{ github.event_name == 'workflow_dispatch' }} && ${{ inputs.commit != ''}} + run: git checkout ${{ inputs.commit }} - - name: Fetch Nomad Certs from S3 + - name: Construct OCI image tag shell: bash run: | - set -euo pipefail + [[ "${{ github.event_name }}" == "push" ]] && \ + echo "IMAGE_TAG=latest" >> $GITHUB_ENV || \ + echo "IMAGE_TAG=canary" >> $GITHUB_ENV - for cert in infra_ca \ - api_client_cert_private_key \ - api_client_cert_public_key; do + - name: Setup Spin + uses: fermyon/actions/spin/setup@v1 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + version: v2.0.1 - aws s3api get-object \ - --bucket "infra-certs-${{ secrets.INFRA_NAMESPACE }}-${{ secrets.AWS_REGION }}" \ - --key "${cert}" \ - "/tmp/${cert}" - done + - name: Configure AWS Credentials for publishing + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.AWS_IAM_ROLE }} + role-session-name: ${{ env.OCI_IMAGE_NAME }} + aws-region: ${{ secrets.AWS_REGION_WEBSITES }} - - name: Configure Nomad - shell: bash - run: | - echo "NOMAD_CACERT=/tmp/infra_ca" >> $GITHUB_ENV - echo "NOMAD_CLIENT_CERT=/tmp/api_client_cert_public_key" >> $GITHUB_ENV - echo "NOMAD_CLIENT_KEY=/tmp/api_client_cert_private_key" >> $GITHUB_ENV - echo "NOMAD_ADDR=https://nomad.${{ secrets.INFRA_NAMESPACE }}.${{ secrets.AWS_REGION }}.fermyon.link:4646" >> $GITHUB_ENV + - name: Log in to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v2 - - name: Configure manual deploy - if: ${{ github.event_name == 'workflow_dispatch' }} - shell: bash + - name: Publish Spin app + id: push + uses: fermyon/actions/spin/push@v1 + with: + registry_reference: ${{ steps.login-ecr.outputs.registry }}/${{ env.OCI_IMAGE_NAME }}:${{ env.IMAGE_TAG }} + manifest_file: docs/spin.toml + + - name: Cleanup login + if: ${{ always() }} run: | - echo "GIT_REF=${{ github.event.inputs.ref }}" >> $GITHUB_ENV - echo "GIT_SHA=${{ github.event.inputs.commit }}" >> $GITHUB_ENV - - if [[ "${{ github.event.inputs.environment }}" == "prod" ]]; then - echo "PRODUCTION=true" >> $GITHUB_ENV - echo "NOMAD_NAMESPACE=prod" >> $GITHUB_ENV - else - echo "PRODUCTION=false" >> $GITHUB_ENV - echo "NOMAD_NAMESPACE=staging" >> $GITHUB_ENV - fi - - - name: Configure auto-deploy - if: ${{ github.event_name == 'push' }} - shell: bash + rm -rf /home/runner/fermyon + + - name: Install Nomad + env: + NOMAD_VERSION: "1.4.3" run: | - echo "GIT_REF=${{ github.ref }}" >> $GITHUB_ENV - echo "GIT_SHA=${{ github.sha }}" >> $GITHUB_ENV + curl -Os https://releases.hashicorp.com/nomad/${NOMAD_VERSION}/nomad_${NOMAD_VERSION}_linux_$(dpkg --print-architecture).zip + unzip nomad_${NOMAD_VERSION}_linux_$(dpkg --print-architecture).zip -d /usr/local/bin + chmod +x /usr/local/bin/nomad - echo "PRODUCTION=true" >> $GITHUB_ENV - echo "NOMAD_NAMESPACE=prod" >> $GITHUB_ENV + - name: Tailscale + uses: tailscale/github-action@v2 + with: + oauth-client-id: ${{ secrets.TS_CI_OAUTH_CLIENT_ID }} + oauth-secret: ${{ secrets.TS_CI_OAUTH_SECRET }} + tags: tag:ci - name: Deploy shell: bash run: | - set -euox pipefail - - # purge any lingering/completed publish jobs - nomad job inspect publish-${{ env.JOB }} &>/dev/null && \ - nomad stop -purge -yes publish-${{ env.JOB }} - - # run the publish job - nomad run \ - -var "region=${{ secrets.AWS_REGION }}" \ - -var "git_ref=${{ env.GIT_REF }}" \ - -var "commit_sha=${{ env.GIT_SHA }}" \ - deploy/publish-${{ env.JOB }}.nomad - - # wait for publish job to complete - timeout 300s bash -c 'until [[ "$(nomad job inspect publish-${{ env.JOB }} | jq -j '.Job.Status')" == "dead" ]]; do sleep 2; done' - - readonly bindle_id="$(nomad logs -job publish-${{ env.JOB }} | sed -n 's/pushed: //p')" + export NOMAD_ADDR="${{ secrets.NOMAD_ADDR }}" + export NOMAD_NAMESPACE=websites - # run/update the website job nomad run \ - -var "region=${{ secrets.AWS_REGION }}" \ - -var "production=${{ env.PRODUCTION }}" \ - -var "bindle_id=${bindle_id}" \ - deploy/${{ env.JOB }}.nomad + -var "region=${{ secrets.AWS_REGION_WEBSITES }}" \ + -var "commit_sha=$(git rev-parse HEAD)" \ + -var "ecr_ref=${{ steps.login-ecr.outputs.registry }}/${{ env.OCI_IMAGE_NAME }}@${{ steps.push.outputs.digest }}" \ + deploy/spin-docs.nomad diff --git a/deploy/README.md b/deploy/README.md index dc32f8d39..26ea3f6dc 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -10,12 +10,10 @@ The production version of the website is deployed whenever commits are pushed to ## Manual Deploys -Deployments may also be [triggered manually](https://github.com/fermyon/spin/actions/workflows/deploy-website.yml), providing a choice of `ref`, `sha` and `environment` (eg canary or prod). +Deployments may also be [triggered manually](https://github.com/fermyon/spin/actions/workflows/deploy-website.yml), providing a choice of `ref` and `sha`. ## Nomad jobs We currently deploy the website via its Nomad job directly. (In the future, we envision running the website as a Fermyon Cloud app.) -The [publish-spin-docs](./publish-spin-docs.nomad) Nomad job checks out this repo's source code and publishes it to Bindle. - -The [spin-docs](./spin-docs.nomad) Nomad job contains configuration for the running website, including the bindle ID to run from. \ No newline at end of file +The [spin-docs](./spin-docs.nomad) Nomad job contains configuration for the running website, including the OCI reference to run from. \ No newline at end of file diff --git a/deploy/publish-spin-docs.nomad b/deploy/publish-spin-docs.nomad deleted file mode 100644 index 241d144ca..000000000 --- a/deploy/publish-spin-docs.nomad +++ /dev/null @@ -1,78 +0,0 @@ -variable "region" { - type = string -} - -variable "git_ref" { - type = string - default = "refs/heads/main" - description = "Git ref to use for the spin repo clone. Default: refs/heads/main" -} - -variable "commit_sha" { - type = string - default = "" - description = "Specific commit SHA to check out. Default: empty/none" -} - -job "publish-spin-docs" { - type = "batch" - datacenters = [ - "${var.region}a", - "${var.region}b", - "${var.region}c", - "${var.region}d", - "${var.region}e", - "${var.region}f" - ] - - group "publish-spin-docs" { - count = 1 - - task "publish-spin-docs" { - driver = "exec" - - artifact { - source = "https://github.com/fermyon/spin/releases/download/v0.10.1/spin-v0.10.1-linux-amd64.tar.gz" - options { - checksum = "sha256:105054335fd76b3d2a1b76a705dbdb3b83d7e4093b302a7816ce7f922893f29d" - } - } - - env { - BINDLE_URL = "http://bindle.service.consul:3030/v1" - } - - template { - data = <<-EOF - #!/bin/bash - set -euo pipefail - - readonly repo_dir="${NOMAD_ALLOC_DIR}/spin" - - # Capture branch/tag name from full ref - readonly branch="$(echo ${var.git_ref} | cut -d'/' -f3-)" - - # Directory and contents may be non-empty if this job is retrying while the - # bindle server is still coming up. (git clone will complain) - rm -rf ${repo_dir} - git clone -b ${branch} https://github.com/fermyon/spin.git ${repo_dir} - cd ${repo_dir}/docs - - # Check out commit if provided - [[ "${var.commit_sha}" == "" ]] || git checkout ${var.commit_sha} - - ${NOMAD_TASK_DIR}/spin bindle push \ - -f spin.toml \ - -d ./staging_dir \ - --buildinfo "g$(git rev-parse HEAD)-$(date '+%Y%m%d%M%H%M%S')" - EOF - destination = "${NOMAD_TASK_DIR}/publish.bash" - perms = "700" - } - - config { - command = "${NOMAD_TASK_DIR}/publish.bash" - } - } - } -} \ No newline at end of file diff --git a/deploy/spin-docs.nomad b/deploy/spin-docs.nomad index e3fe74ea6..536ae6e92 100644 --- a/deploy/spin-docs.nomad +++ b/deploy/spin-docs.nomad @@ -2,48 +2,14 @@ variable "region" { type = string } -variable "production" { - type = bool - default = false - description = "Whether or not this job should run in production mode. Default: false." -} - -variable "dns_domain" { - type = string - default = "fermyon.dev" - description = "The root DNS domain for the Spin docs website, e.g. fermyon.dev, fermyon.link" -} - -variable "hostname" { +variable "ecr_ref" { type = string - default = null - description = "An alternative hostname to use (defaults are .spin.})" -} - -variable "letsencrypt_env" { - type = string - default = "prod" - description = <