From 5c46ba7d55785989da1850a38719270f0a7419a6 Mon Sep 17 00:00:00 2001 From: Jared Moody Date: Wed, 6 May 2026 11:45:37 -0700 Subject: [PATCH 1/4] TF Config for s3 hosting --- .gitignore | 7 ++ .ruby-version | 1 - config.rb | 6 -- infra/buildspec.yml | 21 +++++ infra/main.tf | 219 ++++++++++++++++++++++++++++++++++++++++++++ infra/outputs.tf | 4 + infra/variables.tf | 7 ++ mise.toml | 3 + 8 files changed, 261 insertions(+), 7 deletions(-) delete mode 100644 .ruby-version create mode 100644 infra/buildspec.yml create mode 100644 infra/main.tf create mode 100644 infra/outputs.tf create mode 100644 infra/variables.tf create mode 100644 mise.toml diff --git a/.gitignore b/.gitignore index 1d5d08d..157aa09 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,10 @@ doc/ # Vagrant artifacts ubuntu-*-console.log + +# OpenTofu / Terraform +infra/.terraform/ +infra/.terraform.lock.hcl +infra/terraform.tfstate +infra/terraform.tfstate.backup +infra/terraform.tfvars diff --git a/.ruby-version b/.ruby-version deleted file mode 100644 index 37d02a6..0000000 --- a/.ruby-version +++ /dev/null @@ -1 +0,0 @@ -3.3.8 diff --git a/config.rb b/config.rb index dfc9dd4..4a658a1 100644 --- a/config.rb +++ b/config.rb @@ -32,12 +32,6 @@ activate :sprockets -activate :autoprefixer do |config| - config.browsers = ['last 2 version', 'Firefox ESR'] - config.cascade = false - config.inline = true -end - # Github pages require relative links activate :relative_assets set :relative_links, true diff --git a/infra/buildspec.yml b/infra/buildspec.yml new file mode 100644 index 0000000..0ebd8b8 --- /dev/null +++ b/infra/buildspec.yml @@ -0,0 +1,21 @@ +version: 0.2 + +phases: + install: + runtime-versions: + ruby: 3.3 + commands: + - gem install bundler --no-document + - bundle install --jobs 4 --retry 3 + build: + commands: + - bundle exec middleman build + post_build: + commands: + - | + if [ "$CODEBUILD_BUILD_SUCCEEDING" = "1" ]; then + aws s3 sync build/ s3://$S3_BUCKET/ --delete + else + echo "Build failed, skipping deploy" + exit 1 + fi diff --git a/infra/main.tf b/infra/main.tf new file mode 100644 index 0000000..7830845 --- /dev/null +++ b/infra/main.tf @@ -0,0 +1,219 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.0" + } + } +} + +provider "aws" { + region = "us-east-1" +} + +# S3 bucket for the static site +resource "aws_s3_bucket" "site" { + bucket = var.domain +} + +resource "aws_s3_bucket_website_configuration" "site" { + bucket = aws_s3_bucket.site.id + + index_document { + suffix = "index.html" + } +} + +resource "aws_s3_bucket_public_access_block" "site" { + bucket = aws_s3_bucket.site.id + + block_public_acls = false + block_public_policy = false + ignore_public_acls = false + restrict_public_buckets = false +} + +resource "aws_s3_bucket_policy" "site" { + bucket = aws_s3_bucket.site.id + depends_on = [aws_s3_bucket_public_access_block.site] + + policy = jsonencode({ + Version = "2012-10-17" + Statement = [{ + Effect = "Allow" + Principal = "*" + Action = "s3:GetObject" + Resource = "${aws_s3_bucket.site.arn}/*" + }] + }) +} + +# Artifact bucket for CodePipeline (private) +resource "aws_s3_bucket" "artifacts" { + bucket = "${var.domain}-pipeline-artifacts" +} + +resource "aws_s3_bucket_lifecycle_configuration" "artifacts" { + bucket = aws_s3_bucket.artifacts.id + + rule { + id = "expire" + status = "Enabled" + filter {} + expiration { + days = 7 + } + } +} + +# CodeBuild +resource "aws_iam_role" "codebuild" { + name = "api-docs-codebuild" + + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [{ + Effect = "Allow" + Principal = { Service = "codebuild.amazonaws.com" } + Action = "sts:AssumeRole" + }] + }) +} + +resource "aws_iam_role_policy" "codebuild" { + role = aws_iam_role.codebuild.id + + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Effect = "Allow" + Action = ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"] + Resource = "*" + }, + { + Effect = "Allow" + Action = ["s3:PutObject", "s3:DeleteObject", "s3:ListBucket"] + Resource = [aws_s3_bucket.site.arn, "${aws_s3_bucket.site.arn}/*"] + }, + { + Effect = "Allow" + Action = ["s3:GetObject", "s3:GetObjectVersion", "s3:PutObject"] + Resource = "${aws_s3_bucket.artifacts.arn}/*" + }, + { + Effect = "Allow" + Action = "codestar-connections:UseConnection" + Resource = var.github_connection_arn + } + ] + }) +} + +resource "aws_codebuild_project" "site" { + name = "api-docs" + service_role = aws_iam_role.codebuild.arn + + artifacts { + type = "CODEPIPELINE" + } + + environment { + compute_type = "BUILD_GENERAL1_SMALL" + image = "aws/codebuild/standard:7.0" + type = "LINUX_CONTAINER" + + environment_variable { + name = "S3_BUCKET" + value = aws_s3_bucket.site.bucket + } + } + + source { + type = "CODEPIPELINE" + buildspec = "infra/buildspec.yml" + } +} + +# CodePipeline +resource "aws_iam_role" "codepipeline" { + name = "api-docs-codepipeline" + + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [{ + Effect = "Allow" + Principal = { Service = "codepipeline.amazonaws.com" } + Action = "sts:AssumeRole" + }] + }) +} + +resource "aws_iam_role_policy" "codepipeline" { + role = aws_iam_role.codepipeline.id + + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Effect = "Allow" + Action = ["s3:GetObject", "s3:GetObjectVersion", "s3:PutObject", "s3:ListBucket"] + Resource = [aws_s3_bucket.artifacts.arn, "${aws_s3_bucket.artifacts.arn}/*"] + }, + { + Effect = "Allow" + Action = ["codebuild:BatchGetBuilds", "codebuild:StartBuild"] + Resource = aws_codebuild_project.site.arn + }, + { + Effect = "Allow" + Action = "codestar-connections:UseConnection" + Resource = var.github_connection_arn + } + ] + }) +} + +resource "aws_codepipeline" "site" { + name = "api-docs" + role_arn = aws_iam_role.codepipeline.arn + + artifact_store { + location = aws_s3_bucket.artifacts.bucket + type = "S3" + } + + stage { + name = "Source" + action { + name = "Source" + category = "Source" + owner = "AWS" + provider = "CodeStarSourceConnection" + version = "1" + output_artifacts = ["source"] + configuration = { + ConnectionArn = var.github_connection_arn + FullRepositoryId = "jetbuilt/jetbuilt-api-docs" + BranchName = "main" + OutputArtifactFormat = "CODEBUILD_CLONE_REF" + DetectChanges = "true" + } + } + } + + stage { + name = "Build" + action { + name = "Build" + category = "Build" + owner = "AWS" + provider = "CodeBuild" + version = "1" + input_artifacts = ["source"] + configuration = { + ProjectName = aws_codebuild_project.site.name + } + } + } +} diff --git a/infra/outputs.tf b/infra/outputs.tf new file mode 100644 index 0000000..3da9a95 --- /dev/null +++ b/infra/outputs.tf @@ -0,0 +1,4 @@ +output "site_endpoint" { + description = "S3 website endpoint — use this as the Cloudflare origin" + value = aws_s3_bucket_website_configuration.site.website_endpoint +} diff --git a/infra/variables.tf b/infra/variables.tf new file mode 100644 index 0000000..41435d5 --- /dev/null +++ b/infra/variables.tf @@ -0,0 +1,7 @@ +variable "domain" { + default = "api.jetbuilt.com" +} + +variable "github_connection_arn" { + description = "ARN of the existing CodeStar connection for GitHub" +} diff --git a/mise.toml b/mise.toml new file mode 100644 index 0000000..43c0e28 --- /dev/null +++ b/mise.toml @@ -0,0 +1,3 @@ +[tools] +node = "24" +ruby = "3.3" From 92808f29d4b1e0440d26585036cee5d75e2e8ca1 Mon Sep 17 00:00:00 2001 From: Jared Moody Date: Wed, 6 May 2026 13:53:07 -0700 Subject: [PATCH 2/4] Update deply gh actions versions --- .github/workflows/deploy.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index bb6520f..cdea2f8 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -14,13 +14,13 @@ jobs: ruby-version: 3.3 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v6 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: ruby-version: ${{ env.ruby-version }} - - uses: actions/cache@v3 + - uses: actions/cache@v5 with: path: vendor/bundle key: gems-${{ runner.os }}-${{ env.ruby-version }}-${{ hashFiles('**/Gemfile.lock') }} @@ -37,7 +37,7 @@ jobs: - run: bundle exec middleman build - name: Deploy - uses: peaceiris/actions-gh-pages@v3 + uses: peaceiris/actions-gh-pages@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./build From a32356466b7ec2a53971f47b14bcaa69d35d7fae Mon Sep 17 00:00:00 2001 From: Jared Moody Date: Wed, 6 May 2026 13:56:08 -0700 Subject: [PATCH 3/4] Update buildspec.yml --- infra/buildspec.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infra/buildspec.yml b/infra/buildspec.yml index 0ebd8b8..4299fa3 100644 --- a/infra/buildspec.yml +++ b/infra/buildspec.yml @@ -9,7 +9,7 @@ phases: - bundle install --jobs 4 --retry 3 build: commands: - - bundle exec middleman build + - bundle exec middleman build --verbose post_build: commands: - | From bd622e57d5a33d685b291f10ab9359e099ac0260 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 May 2026 20:57:05 +0000 Subject: [PATCH 4/4] Bump nokogiri from 1.19.1 to 1.19.3 Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.19.1 to 1.19.3. - [Release notes](https://github.com/sparklemotion/nokogiri/releases) - [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md) - [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.19.1...v1.19.3) --- updated-dependencies: - dependency-name: nokogiri dependency-version: 1.19.3 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index ac90ef4..248ab89 100644 --- a/Gemfile +++ b/Gemfile @@ -8,6 +8,6 @@ gem 'middleman-autoprefixer', '~> 3.0' gem 'middleman-sprockets', '~> 4.1' gem 'rouge', '~> 3.21' gem 'redcarpet', '~> 3.6.0' -gem 'nokogiri', '~> 1.19.1' +gem 'nokogiri', '~> 1.19.3' gem 'sass' gem 'webrick' diff --git a/Gemfile.lock b/Gemfile.lock index cb0f705..80d7a27 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -93,7 +93,7 @@ GEM rouge (~> 3.2) mini_portile2 (2.8.9) minitest (5.27.0) - nokogiri (1.19.1) + nokogiri (1.19.3) mini_portile2 (~> 2.8.2) racc (~> 1.4) padrino-helpers (0.15.2) @@ -146,7 +146,7 @@ DEPENDENCIES middleman-autoprefixer (~> 3.0) middleman-sprockets (~> 4.1) middleman-syntax (~> 3.2) - nokogiri (~> 1.19.1) + nokogiri (~> 1.19.3) redcarpet (~> 3.6.0) rouge (~> 3.21) sass