From 702fcf40de3f94a8a971521aa46af0ad2ca832d4 Mon Sep 17 00:00:00 2001 From: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com> Date: Mon, 30 Jun 2025 23:53:23 +0200 Subject: [PATCH 01/10] dev DB --- src/controllers/categoriesController.js | 6 ++++++ terraform/dev/variables.tf | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/controllers/categoriesController.js b/src/controllers/categoriesController.js index 6a76918..c000a04 100644 --- a/src/controllers/categoriesController.js +++ b/src/controllers/categoriesController.js @@ -20,6 +20,7 @@ const listCategories = async (req, res) => { */ const isOnlyNames = params.onlyname || typeof params.onlyname === 'string'; + const client = params.client || 'mobile'; // Default client if not provided const hasCustomFields = params.fields && !isOnlyNames; let query = firestore.collection('categories').orderBy('category', 'asc'); @@ -32,6 +33,11 @@ const listCategories = async (req, res) => { } } + // Apply client filter + if (client) { + query = query.where('client', '==', client); + } + // Apply field selection if (isOnlyNames) { query = query.select('category'); diff --git a/terraform/dev/variables.tf b/terraform/dev/variables.tf index 77e6d54..5869e96 100644 --- a/terraform/dev/variables.tf +++ b/terraform/dev/variables.tf @@ -15,7 +15,7 @@ variable "environment" { variable "project_database" { type = string description = "The database name" - default = "tech-report-api-prod" // TODO: Update this to the DEV database name + default = "tech-report-api-dev" } variable "google_service_account_cloud_functions" { From 1792820f983bdc7bf082b818e91b060ccaec65bd Mon Sep 17 00:00:00 2001 From: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com> Date: Tue, 1 Jul 2025 00:29:56 +0200 Subject: [PATCH 02/10] selected fields --- README.md | 19 +++++++------------ src/controllers/categoriesController.js | 4 ++-- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 2724719..9772f00 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ Lists available categories. #### Categories Parameters - `category` (optional): Filter by category name(s) - comma-separated list +- `client` (optional): Filter by client type (e.g., `mobile`, `desktop`) - defaults to `mobile` - `onlyname` (optional): If present, returns only category names - `fields` (optional): Comma-separated list of fields to include in the response (see [Field Selection API Documentation](#field-selection-api-documentation) for details) @@ -63,7 +64,7 @@ Lists available categories. ```bash curl --request GET \ - --url 'https://d{{HOST}}/v1/categories?category=Domain%20parking%2CCI' + --url 'https://{{HOST}}/v1/categories?category=Domain%20parking%2CCI&client=desktop' ``` ```json @@ -74,10 +75,7 @@ curl --request GET \ "Jenkins", "TeamCity" ], - "origins": { - "mobile": 22, - "desktop": 35 - }, + "origins": 22, "category": "CI" }, { @@ -86,10 +84,7 @@ curl --request GET \ "Cloudflare", "Arsys Domain Parking" ], - "origins": { - "mobile": 14, - "desktop": 8 - }, + "origins": 14, "category": "Domain parking" } ] @@ -588,7 +583,7 @@ The categories and technologies endpoints now support custom field selection, al - `category` - Category name - `description` - Category description - `technologies` - Array of technology names in the category -- `origins` - Array of origin companies/organizations +- `origins` - Number of origins Get only category names: @@ -608,7 +603,7 @@ GET /v1/categories?fields=category,description - `category` - Category name - `description` - Technology description - `icon` - Icon filename -- `origins` - Array of origin companies/organizations +- `origins` - Dictionary with origins per client Get only technology names and categories: @@ -643,7 +638,7 @@ GET /v1/technologies?category=JavaScript%20Frameworks&fields=technology,icon - `technology` - Technology name - `version` - Version name -- `origins` - Mobile and desktop origins +- `origins` - Dictionary with origins per client Get only technology and version names: diff --git a/src/controllers/categoriesController.js b/src/controllers/categoriesController.js index c000a04..a1a0a5e 100644 --- a/src/controllers/categoriesController.js +++ b/src/controllers/categoriesController.js @@ -8,7 +8,7 @@ const listCategories = async (req, res) => { const queryBuilder = async (params) => { /* // Validate parameters - const supportedParams = ['category', 'onlyname', 'fields']; + const supportedParams = ['category', 'onlyname', 'fields', 'client']; const providedParams = Object.keys(params); const unsupportedParams = providedParams.filter(param => !supportedParams.includes(param)); @@ -42,7 +42,7 @@ const listCategories = async (req, res) => { if (isOnlyNames) { query = query.select('category'); } else if (hasCustomFields) { - const requestedFields = params.fields.split(',').map(f => f.trim()); + const requestedFields = params.fields.split(',').map(f => f.trim()) || ['category', 'description', 'technologies', 'origins']; query = query.select(...requestedFields); } From da93de64bb856085de1982431ba7a012152c3021 Mon Sep 17 00:00:00 2001 From: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com> Date: Tue, 1 Jul 2025 00:49:56 +0200 Subject: [PATCH 03/10] cache key expanded --- src/controllers/categoriesController.js | 4 +++- src/controllers/technologiesController.js | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/controllers/categoriesController.js b/src/controllers/categoriesController.js index a1a0a5e..84f7b79 100644 --- a/src/controllers/categoriesController.js +++ b/src/controllers/categoriesController.js @@ -62,7 +62,9 @@ const listCategories = async (req, res) => { // Include onlyname and fields in cache key calculation const customCacheKeyData = { onlyname: req.query.onlyname || false, - fields: req.query.fields + fields: req.query.fields, + category: req.query.category ? validateArrayParameter(req.query.category, 'category') : [], + client: req.query.client || 'mobile', }; await executeQuery(req, res, 'categories', queryBuilder, dataProcessor, customCacheKeyData); diff --git a/src/controllers/technologiesController.js b/src/controllers/technologiesController.js index 5d75aba..1858a8a 100644 --- a/src/controllers/technologiesController.js +++ b/src/controllers/technologiesController.js @@ -69,7 +69,9 @@ const listTechnologies = async (req, res) => { // Include onlyname and fields in cache key calculation const customCacheKeyData = { onlyname: req.query.onlyname || false, - fields: req.query.fields + fields: req.query.fields, + technology: req.query.technology ? validateTechnologyArray(req.query.technology) : [], + category: req.query.category ? validateArrayParameter(req.query.category, 'category') : [], }; await executeQuery(req, res, 'technologies', queryBuilder, dataProcessor, customCacheKeyData); From f9023cc28e6829cc62a1ef27903cade234870b58 Mon Sep 17 00:00:00 2001 From: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com> Date: Mon, 7 Jul 2025 22:43:24 +0200 Subject: [PATCH 04/10] versions endpoint --- src/controllers/reportController.js | 7 +++---- terraform/dev/main.tf | 7 +++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/controllers/reportController.js b/src/controllers/reportController.js index 9f24123..b3db81c 100644 --- a/src/controllers/reportController.js +++ b/src/controllers/reportController.js @@ -1,5 +1,4 @@ -import { firestoreOld } from '../utils/db.js'; -const firestore = firestoreOld; +import { firestore } from '../utils/db.js'; import { REQUIRED_PARAMS, @@ -117,9 +116,9 @@ const createReportController = (reportType) => { // Apply version filter with special handling for 'ALL' case if (params.version && techArray.length === 1) { - //query = query.where('version', '==', params.version); // TODO: Uncomment when migrating to a new data schema + query = query.where('version', '==', params.version); } else { - //query = query.where('version', '==', 'ALL'); + query = query.where('version', '==', 'ALL'); } // Apply date filters diff --git a/terraform/dev/main.tf b/terraform/dev/main.tf index db15672..87f7c6b 100644 --- a/terraform/dev/main.tf +++ b/terraform/dev/main.tf @@ -98,6 +98,13 @@ paths: responses: 200: description: String + /v1/versions: + get: + summary: versions + operationId: getVersions + responses: + 200: + description: String /v1/audits: get: summary: audits From 8cab936adcac3c5e5829c4071977d0a196a78ddf Mon Sep 17 00:00:00 2001 From: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com> Date: Tue, 8 Jul 2025 23:04:00 +0200 Subject: [PATCH 05/10] Add version parameter support to report data endpoints --- README.md | 5 +++++ src/__tests__/routes.test.js | 6 ++++++ src/controllers/reportController.js | 32 ++++++++++++++++++----------- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 9772f00..7c999b1 100644 --- a/README.md +++ b/README.md @@ -208,6 +208,7 @@ Provides technology adoption data. - `rank` (required): Filter by rank - `start` (optional): Filter by date range start (YYYY-MM-DD or 'latest') - `end` (optional): Filter by date range end (YYYY-MM-DD) +- `version` (optional): Filter by version name(s) - comma-separated list (only when single technology is specified) #### Adoption Response @@ -243,6 +244,7 @@ Provides Core Web Vitals metrics for technologies. - `rank` (required): Filter by rank - `start` (optional): Filter by date range start (YYYY-MM-DD or 'latest') - `end` (optional): Filter by date range end (YYYY-MM-DD) +- `version` (optional): Filter by version name(s) - comma-separated list (only when single technology is specified) #### CWV Response @@ -286,6 +288,7 @@ Provides Lighthouse scores for technologies. - `rank` (required): Filter by rank - `start` (optional): Filter by date range start (YYYY-MM-DD or 'latest') - `end` (optional): Filter by date range end (YYYY-MM-DD) +- `version` (optional): Filter by version name(s) - comma-separated list (only when single technology is specified) #### Lighthouse Response @@ -333,6 +336,7 @@ Provides Page Weight metrics for technologies. - `rank` (required): Filter by rank - `start` (optional): Filter by date range start (YYYY-MM-DD or 'latest') - `end` (optional): Filter by date range end (YYYY-MM-DD) +- `version` (optional): Filter by version name(s) - comma-separated list (only when single technology is specified) #### Page Weight Response @@ -394,6 +398,7 @@ Provides Lighthouse audits for technologies. - `rank` (required): Filter by rank - `start` (optional): Filter by date range start (YYYY-MM-DD or 'latest') - `end` (optional): Filter by date range end (YYYY-MM-DD) +- `version` (optional): Filter by version name(s) - comma-separated list (only when single technology is specified) #### Audits Response diff --git a/src/__tests__/routes.test.js b/src/__tests__/routes.test.js index f84cd9b..38f5d48 100644 --- a/src/__tests__/routes.test.js +++ b/src/__tests__/routes.test.js @@ -233,6 +233,12 @@ describe('API Routes', () => { expect(Array.isArray(res.body)).toBe(true); }); + it('should return adoption data with version parameter', async () => { + const res = await request(app).get('/v1/adoption?technology=WordPress&geo=ALL&rank=ALL&start=latest&version=5.0'); + expect(res.statusCode).toEqual(200); + expect(Array.isArray(res.body)).toBe(true); + }); + it('should handle missing required parameters', async () => { const res = await request(app).get('/v1/adoption'); expect(res.statusCode).toEqual(400); diff --git a/src/controllers/reportController.js b/src/controllers/reportController.js index b3db81c..14ffaf7 100644 --- a/src/controllers/reportController.js +++ b/src/controllers/reportController.js @@ -54,7 +54,7 @@ const createReportController = (reportType) => { /* // Validate supported parameters - const supportedParams = ['technology', 'geo', 'rank', 'start', 'end']; + const supportedParams = ['technology', 'geo', 'rank', 'start', 'end', 'version']; const providedParams = Object.keys(params); const unsupportedParams = providedParams.filter(param => !supportedParams.includes(param)); @@ -77,8 +77,15 @@ const createReportController = (reportType) => { return; } - // Validate and process technology array - const techArray = validateArrayParameter(params.technology, 'technology'); + // Validate and process technologies + const technologiesArray = validateArrayParameter(params.technology, 'technology'); + + // Validate and process versions + // Apply version filter with special handling for 'ALL' case + let versionsArray = ['ALL']; + if (technologiesArray.length === 1 && params.version) { + versionsArray = validateArrayParameter(params.version, 'version'); + } // Handle 'latest' date substitution let startDate = params.start; @@ -90,7 +97,8 @@ const createReportController = (reportType) => { const queryFilters = { geo: params.geo, rank: params.rank, - technology: techArray, + technology: technologiesArray, + version: versionsArray, startDate: startDate, endDate: params.end }; @@ -112,21 +120,21 @@ const createReportController = (reportType) => { query = query.where('rank', '==', params.rank); // Apply technology filter with batch processing - query = query.where('technology', 'in', techArray); + query = query.where('technology', 'in', technologiesArray); - // Apply version filter with special handling for 'ALL' case - if (params.version && techArray.length === 1) { - query = query.where('version', '==', params.version); - } else { - query = query.where('version', '==', 'ALL'); - } + // Apply version filter with batch processing + query = query.where('version', 'in', versionsArray); // Apply date filters if (startDate) query = query.where('date', '>=', startDate); if (params.end) query = query.where('date', '<=', params.end); // Apply field projection to optimize query - query = query.select('date', 'technology', config.dataField); + const selectFields = ['date', 'technology', config.dataField]; + if (!(versionsArray.length === 1 && versionsArray[0] === 'ALL')) { + selectFields.push('version'); + } + query = query.select(...selectFields); // Execute query const snapshot = await query.get(); From 09dae53f3b1a2a578a302867dc33d90347b47d97 Mon Sep 17 00:00:00 2001 From: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com> Date: Tue, 15 Jul 2025 12:52:37 +0200 Subject: [PATCH 06/10] docker builds --- src/.dockerignore | 12 +++ src/Dockerfile | 17 ++++ src/package.json | 4 +- terraform/dev/local.auto.tfvars.template | 4 - terraform/dev/main.tf | 106 +++++++++++---------- terraform/modules/api-gateway/main.tf | 36 ++++--- terraform/modules/api-gateway/variables.tf | 5 + terraform/modules/run-service/docker.tf | 20 ++++ terraform/modules/run-service/main.tf | 106 +++++++++------------ terraform/modules/run-service/outputs.tf | 5 +- terraform/modules/run-service/variables.tf | 13 +-- terraform/prod/local.auto.tfvars.template | 4 - terraform/prod/main.tf | 89 +++++++++-------- 13 files changed, 234 insertions(+), 187 deletions(-) create mode 100644 src/.dockerignore create mode 100644 src/Dockerfile delete mode 100644 terraform/dev/local.auto.tfvars.template create mode 100644 terraform/modules/run-service/docker.tf delete mode 100644 terraform/prod/local.auto.tfvars.template diff --git a/src/.dockerignore b/src/.dockerignore new file mode 100644 index 0000000..28a5ebd --- /dev/null +++ b/src/.dockerignore @@ -0,0 +1,12 @@ +node_modules +npm-debug.log +.git +.gitignore +.env +.nyc_output +coverage +*.md +.DS_Store +cloudbuild.yaml +__tests__ +coverage diff --git a/src/Dockerfile b/src/Dockerfile new file mode 100644 index 0000000..15a1abd --- /dev/null +++ b/src/Dockerfile @@ -0,0 +1,17 @@ +FROM node:22-slim + +# Set the working directory +WORKDIR /app + +# Copy package files first for better layer caching +COPY package*.json ./ + +# Install dependencies (this layer will be cached unless package files change) +RUN npm ci --only=production --quiet --no-fund --no-audit && npm cache clean --force + +ENV DATABASE=tech-report-api-prod + +# Copy source code +COPY . . + +CMD ["node", "index.js"] diff --git a/src/package.json b/src/package.json index c9764ac..2e0bfa8 100644 --- a/src/package.json +++ b/src/package.json @@ -10,7 +10,9 @@ "scripts": { "start": "export DATABASE=tech-report-api-prod && node index.js", "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js", - "test:live": "bash ../test-api.sh" + "test:live": "bash ../test-api.sh", + "build": "docker build -t tech-report-api .", + "run": "docker run -p 8080:8080 tech-report-api" }, "dependencies": { "@google-cloud/firestore": "7.11.2", diff --git a/terraform/dev/local.auto.tfvars.template b/terraform/dev/local.auto.tfvars.template deleted file mode 100644 index 3ebe52e..0000000 --- a/terraform/dev/local.auto.tfvars.template +++ /dev/null @@ -1,4 +0,0 @@ -google_service_account_api_gateway = "" -google_service_account_cloud_functions = "" -project_database = "" - diff --git a/terraform/dev/main.tf b/terraform/dev/main.tf index 87f7c6b..6b14711 100644 --- a/terraform/dev/main.tf +++ b/terraform/dev/main.tf @@ -3,6 +3,13 @@ terraform { bucket = "tfstate-httparchive" prefix = "tech-report-apis/dev" } + + required_providers { + docker = { + source = "kreuzwerker/docker" + version = ">= 3.6.2" + } + } } provider "google" { @@ -11,23 +18,30 @@ provider "google" { request_timeout = "60m" } -resource "google_api_gateway_api" "api" { - provider = google-beta - api_id = "reports-api-dev" - display_name = "Reports API Gateway DEV" - project = var.project +provider "google-beta" { + project = var.project + region = var.region +} + +# Get current Google Cloud access token +data "google_client_config" "default" {} + +# Configure Docker provider with Artifact Registry authentication +provider "docker" { + registry_auth { + address = "${var.region}-docker.pkg.dev" + username = "oauth2accesstoken" + password = data.google_client_config.default.access_token + } } -resource "google_api_gateway_api_config" "api_config" { - provider = google-beta - api = google_api_gateway_api.api.api_id - api_config_id_prefix = "reports-api-config-dev" - project = var.project - display_name = "Reports API Config DEV" - openapi_documents { - document { - path = "spec.yaml" - contents = base64encode(<<-EOF +module "gateway" { + source = "./../modules/api-gateway" + project = var.project + environment = var.environment + region = var.region + service_account_email = var.google_service_account_api_gateway + spec_yaml = < Date: Tue, 15 Jul 2025 12:59:02 +0200 Subject: [PATCH 07/10] fix paths --- terraform/modules/run-service/docker.tf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/terraform/modules/run-service/docker.tf b/terraform/modules/run-service/docker.tf index 978c0ba..c031ba7 100644 --- a/terraform/modules/run-service/docker.tf +++ b/terraform/modules/run-service/docker.tf @@ -1,15 +1,15 @@ # Calculate hash of source files to determine if rebuild is needed locals { - source_files = fileset(path.root, "../${var.function_name}/*") + source_files = fileset(path.root, "${var.source_directory}/*") source_hash = substr(sha1(join("", [for f in local.source_files : filesha1(f)])), 0, 8) } # Build Docker image resource "docker_image" "function_image" { - name = "${var.region}-docker.pkg.dev/${var.project}/dataform/${var.function_name}:${local.source_hash}" + name = "${var.region}-docker.pkg.dev/${var.project}/cloud-run/${var.function_name}:${local.source_hash}" build { - context = "../${var.function_name}/" + context = var.source_directory dockerfile = "Dockerfile" platform = "linux/amd64" } From c59fa3c0a51ab3dc5625a803f6e2f1da3f20b279 Mon Sep 17 00:00:00 2001 From: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com> Date: Tue, 15 Jul 2025 13:01:43 +0200 Subject: [PATCH 08/10] rename repo --- terraform/modules/run-service/docker.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terraform/modules/run-service/docker.tf b/terraform/modules/run-service/docker.tf index c031ba7..aa5a271 100644 --- a/terraform/modules/run-service/docker.tf +++ b/terraform/modules/run-service/docker.tf @@ -6,7 +6,7 @@ locals { # Build Docker image resource "docker_image" "function_image" { - name = "${var.region}-docker.pkg.dev/${var.project}/cloud-run/${var.function_name}:${local.source_hash}" + name = "${var.region}-docker.pkg.dev/${var.project}/tech-report-api/${var.function_name}:${local.source_hash}" build { context = var.source_directory From ad93b49c2613721c87b80b5daf44cbc99ca3961e Mon Sep 17 00:00:00 2001 From: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com> Date: Tue, 15 Jul 2025 13:11:01 +0200 Subject: [PATCH 09/10] fix iam --- terraform/dev/main.tf | 22 +++++++++++----------- terraform/modules/api-gateway/variables.tf | 2 +- terraform/modules/run-service/main.tf | 16 ---------------- terraform/prod/main.tf | 22 +++++++++++----------- 4 files changed, 23 insertions(+), 39 deletions(-) diff --git a/terraform/dev/main.tf b/terraform/dev/main.tf index 6b14711..235a551 100644 --- a/terraform/dev/main.tf +++ b/terraform/dev/main.tf @@ -19,8 +19,8 @@ provider "google" { } provider "google-beta" { - project = var.project - region = var.region + project = var.project + region = var.region } # Get current Google Cloud access token @@ -36,12 +36,12 @@ provider "docker" { } module "gateway" { - source = "./../modules/api-gateway" - project = var.project - environment = var.environment - region = var.region - service_account_email = var.google_service_account_api_gateway - spec_yaml = < Date: Tue, 15 Jul 2025 13:29:46 +0200 Subject: [PATCH 10/10] cleanup --- terraform/dev/main.tf | 7 +++-- terraform/modules/api-gateway/variables.tf | 2 ++ terraform/modules/run-service/docker.tf | 20 --------------- terraform/modules/run-service/main.tf | 30 +++++++++++++++++----- terraform/modules/run-service/variables.tf | 24 +++-------------- terraform/prod/main.tf | 15 +++-------- 6 files changed, 35 insertions(+), 63 deletions(-) delete mode 100644 terraform/modules/run-service/docker.tf diff --git a/terraform/dev/main.tf b/terraform/dev/main.tf index 235a551..94527ad 100644 --- a/terraform/dev/main.tf +++ b/terraform/dev/main.tf @@ -36,7 +36,7 @@ provider "docker" { } module "gateway" { - source = "./../modules/api-gateway" + source = "../modules/api-gateway" project = var.project environment = var.environment region = var.region @@ -130,12 +130,11 @@ EOF } module "endpoints" { - source = "./../modules/run-service" - entry_point = "app" + source = "../modules/run-service" project = var.project environment = var.environment source_directory = "../../src" - function_name = "tech-report-api" + service_name = "tech-report-api" region = var.region service_account_email = var.google_service_account_cloud_functions service_account_api_gateway = var.google_service_account_api_gateway diff --git a/terraform/modules/api-gateway/variables.tf b/terraform/modules/api-gateway/variables.tf index de830f8..60ea31e 100644 --- a/terraform/modules/api-gateway/variables.tf +++ b/terraform/modules/api-gateway/variables.tf @@ -6,10 +6,12 @@ variable "environment" { variable "project" { description = "The ID of the project in which the resource belongs. If it is not provided, the provider project is used." type = string + default = "httparchive" } variable "region" { description = "The Region of this resource" type = string + default = "us-central1" } variable "service_account_email" { description = "Email of the service account associated with and to run the API Gateway" diff --git a/terraform/modules/run-service/docker.tf b/terraform/modules/run-service/docker.tf deleted file mode 100644 index aa5a271..0000000 --- a/terraform/modules/run-service/docker.tf +++ /dev/null @@ -1,20 +0,0 @@ -# Calculate hash of source files to determine if rebuild is needed -locals { - source_files = fileset(path.root, "${var.source_directory}/*") - source_hash = substr(sha1(join("", [for f in local.source_files : filesha1(f)])), 0, 8) -} - -# Build Docker image -resource "docker_image" "function_image" { - name = "${var.region}-docker.pkg.dev/${var.project}/tech-report-api/${var.function_name}:${local.source_hash}" - - build { - context = var.source_directory - dockerfile = "Dockerfile" - platform = "linux/amd64" - } -} - -resource "docker_registry_image" "registry_image" { - name = docker_image.function_image.name -} diff --git a/terraform/modules/run-service/main.tf b/terraform/modules/run-service/main.tf index 75e4380..312e625 100644 --- a/terraform/modules/run-service/main.tf +++ b/terraform/modules/run-service/main.tf @@ -7,12 +7,33 @@ terraform { } } +# Calculate hash of source files to determine if rebuild is needed +locals { + source_files = fileset(path.root, "${var.source_directory}/*") + source_hash = substr(sha1(join("", [for f in local.source_files : filesha1(f)])), 0, 8) +} + +# Build Docker image +resource "docker_image" "function_image" { + name = "${var.region}-docker.pkg.dev/${var.project}/tech-report-api/${var.service_name}:${local.source_hash}" + + build { + context = var.source_directory + dockerfile = "Dockerfile" + platform = "linux/amd64" + } +} + +resource "docker_registry_image" "registry_image" { + name = docker_image.function_image.name +} + resource "google_cloud_run_v2_service" "service" { - name = "${var.function_name}-${var.environment}" + name = "${var.service_name}-${var.environment}" location = var.region deletion_protection = false - ingress = var.ingress_settings + ingress = "INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER" template { service_account = var.service_account_email @@ -32,16 +53,11 @@ resource "google_cloud_run_v2_service" "service" { value = env.value } } - } - - timeout = var.timeout max_instance_request_concurrency = var.max_instance_request_concurrency - } scaling { - min_instance_count = var.min_instances } traffic { diff --git a/terraform/modules/run-service/variables.tf b/terraform/modules/run-service/variables.tf index 5f1037a..659dd0d 100644 --- a/terraform/modules/run-service/variables.tf +++ b/terraform/modules/run-service/variables.tf @@ -5,19 +5,16 @@ variable "region" { variable "environment" { description = "The 'Environment' that is being created/deployed. Applied as a suffix to many resources." type = string + default = "dev" } variable "source_directory" { description = "The folder of the package containing function that will be executed when the Google Cloud Function is triggered!" type = string } -variable "function_name" { +variable "service_name" { description = "Optional: Can be used to create more than function from the same package" type = string } -variable "entry_point" { - description = "The entry point; This is either what is registered with 'http' or exported from the code as a handler!" - type = string -} variable "available_memory_gb" { default = "2Gi" type = string @@ -28,19 +25,10 @@ variable "available_cpu" { type = string description = "The amount of CPU for the Cloud Function" } -variable "ingress_settings" { - type = string - default = "INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER" - description = "String value that controls what traffic can reach the function. Allowed values are ALLOW_ALL, ALLOW_INTERNAL_AND_GCLB and ALLOW_INTERNAL_ONLY. Check ingress documentation to see the impact of each settings value. Changes to this field will recreate the cloud function." -} -variable "vpc_connector_egress_settings" { - type = string - default = null - description = "The egress settings for the connector, controlling what traffic is diverted through it. Allowed values are ALL_TRAFFIC and PRIVATE_RANGES_ONLY. Defaults to PRIVATE_RANGES_ONLY. If unset, this field preserves the previously set value." -} variable "project" { description = "The ID of the project in which the resource belongs. If it is not provided, the provider project is used." type = string + default = "httparchive" } variable "timeout" { default = "60s" @@ -55,11 +43,7 @@ variable "service_account_api_gateway" { type = string description = "API Gateway service account who can invoke this function. This is required!" } -variable "max_instances" { - default = 10 - type = number - description = "(Optional) The limit on the maximum number of function instances that may coexist at a given time." -} + variable "min_instances" { description = "(Optional) The limit on the minimum number of function instances that may coexist at a given time." type = number diff --git a/terraform/prod/main.tf b/terraform/prod/main.tf index cfbbd54..48b2fe8 100644 --- a/terraform/prod/main.tf +++ b/terraform/prod/main.tf @@ -22,7 +22,6 @@ provider "google-beta" { region = var.region } - # Get current Google Cloud access token data "google_client_config" "default" {} @@ -35,13 +34,9 @@ provider "docker" { } } - - module "gateway" { - source = "./../modules/api-gateway" - project = var.project + source = "../modules/api-gateway" environment = var.environment - region = var.region service_account_email = var.google_service_account_api_gateway spec_yaml = <