Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion .github/workflows/module-definitions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
fetch-depth: 0

- name: Setup Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
Expand Down Expand Up @@ -109,6 +111,20 @@ jobs:
env:
RAVION_API_TOKEN: ${{ secrets.RAVION_API_TOKEN }}

- name: Generate module category source diff
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
run: |
if git diff --quiet "$BASE_SHA" HEAD -- tools/ravion-modules/src/module-categories.ts; then
exit 0
fi
{
printf '### Module Category Changes\n\n'
printf '```diff\n'
git diff --no-ext-diff --unified=3 "$BASE_SHA" HEAD -- tools/ravion-modules/src/module-categories.ts
printf '```\n'
} > category-diff.md

- name: Comment publish dry-run plan
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
if: always()
Expand All @@ -118,9 +134,12 @@ jobs:
const marker = '<!-- ravion-module-publish-plan -->';
const planPath = 'publish-plan.md';
const errorPath = 'publish-plan.err';
const categoryDiffPath = 'category-diff.md';
const plan = fs.existsSync(planPath) ? fs.readFileSync(planPath, 'utf8') : '';
const error = fs.existsSync(errorPath) ? fs.readFileSync(errorPath, 'utf8').trim().slice(-2000) : '';
const body = plan || `${marker}\n## Ravion Module Publish Plan\n\nPublish dry run failed before a plan could be generated.\n\n\`\`\`text\n${error || 'No error output was captured.'}\n\`\`\``;
const categoryDiff = fs.existsSync(categoryDiffPath) ? fs.readFileSync(categoryDiffPath, 'utf8').trim() : '';
const publishBody = plan || `${marker}\n## Ravion Module Publish Plan\n\nPublish dry run failed before a plan could be generated.\n\n\`\`\`text\n${error || 'No error output was captured.'}\n\`\`\``;
const body = `${publishBody.trimEnd()}${categoryDiff ? `\n\n${categoryDiff}` : ''}`;
const { owner, repo } = context.repo;
const issue_number = context.issue.number;
const comments = await github.paginate(github.rest.issues.listComments, { owner, repo, issue_number, per_page: 100 });
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ sync by `node tools/ravion-modules/dist/src/cli.js readme` (enforced in CI, and
| `rvn-cloudfront` | CloudFront CDN | v1.3.0 | `cdn/cloudfront/` |
| `rvn-ec2-service` | EC2 Service | v1.4.1 | `compute/ec2_service/` |
| `rvn-ecs-cluster` | ECS Cluster | v1.0.1 | `compute/ecs_cluster/` |
| `rvn-ecs-nlb` | ECS Network Service | v1.1.0 | `compute/ecs_service/` |
| `rvn-ecs-nlb` | ECS Network Service | v1.1.1 | `compute/ecs_service/` |
| `rvn-ecs-web` | ECS Web Service | v1.1.0 | `compute/ecs_service/` |
| `rvn-ecs-worker` | ECS Worker | v1.1.0 | `compute/ecs_service/` |
| `rvn-efs` | EFS File System | v1.0.1 | `storage/efs/` |
Expand Down
8 changes: 4 additions & 4 deletions compute/ecs_service/rvn-ecs-nlb-definition.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
definition:
type: rvn-ecs-nlb
name: ECS Network Service
description: Network Load Balanced ECS service for running TCP, UDP, or TLS workloads behind an ECS cluster Network Load Balancer.
description: Network Load Balanced ECS service for exposing one to five TCP, UDP, or TLS ports through an ECS cluster Network Load Balancer.
release:
version: 1.1.0
description: Add Builder IAM policies inputs that attach extra IAM managed policies to the EC2 build runner role or replace the step default policies entirely for the duration of each build.
version: 1.1.1
description: Clarify that one ECS Network Service can expose up to five TCP, UDP, or TLS ports.
module:
inputs:
- id: section_cluster
Expand Down Expand Up @@ -446,7 +446,7 @@ module:
region: << stack.output.region >>
statistic: Average
readme: |
Network Load Balanced ECS service for running TCP, UDP, or TLS workloads behind an ECS cluster Network Load Balancer.
Network Load Balanced ECS service for exposing one to five TCP, UDP, or TLS ports through an ECS cluster Network Load Balancer.

## Overview

Expand Down
3 changes: 3 additions & 0 deletions tools/ravion-modules/src/generate-definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import YAML from "yaml";

export interface RemoteModuleDefinition {
id: string;
organizationId?: string;
type: string;
name: string;
description: string;
moduleCategoryIds?: string[];
moduleCategoryId?: string | null;
isGlobalPublished?: boolean;
}

Expand Down
125 changes: 125 additions & 0 deletions tools/ravion-modules/src/module-categories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
export interface ModuleCategorySpec {
givenId: string;
name: string;
description: string;
sortOrder: number;
definitionTypes: readonly string[];
previousGivenIds?: readonly string[];
}

export const MODULE_CATEGORIES: readonly ModuleCategorySpec[] = [
{
givenId: "web-server",
name: "Web server",
description: "For websites, HTTP APIs, and services reached through a browser or web client.",
sortOrder: 10,
definitionTypes: ["rvn-ec2-service", "rvn-ecs-nlb", "rvn-ecs-web"],
},
{
givenId: "tcp-udp-server",
name: "TCP/UDP server",
description: "For Layer 4 workloads such as game servers, MQTT brokers, and custom TCP, UDP, or TLS protocols.",
sortOrder: 20,
definitionTypes: ["rvn-ecs-nlb"],
previousGivenIds: ["tcp-udp-service"],
},
{
givenId: "worker",
name: "Worker",
description: "For queue consumers, scheduled jobs, and background processes without public endpoints.",
sortOrder: 30,
definitionTypes: ["rvn-ec2-service", "rvn-ecs-worker"],
},
{
givenId: "function",
name: "Function",
description: "For webhook handlers, scheduled tasks, and event processing that run only when invoked.",
sortOrder: 40,
definitionTypes: ["rvn-lambda"],
},
{
givenId: "static-site",
name: "Static site",
description: "For frontend assets, documentation, and single-page apps that do not need an always-on server.",
sortOrder: 50,
definitionTypes: ["rvn-aws-static"],
},
{
givenId: "database",
name: "Database",
description: "For relational data such as PostgreSQL or MySQL, including connection pooling.",
sortOrder: 60,
definitionTypes: ["rvn-aurora", "rvn-rds", "rvn-rds-proxy"],
},
{
givenId: "cache",
name: "Cache",
description: "For Redis or Memcached workloads that need low-latency shared state.",
sortOrder: 70,
definitionTypes: ["rvn-elasticache"],
},
{
givenId: "storage",
name: "Storage",
description: "For uploads, backups, and shared files that need persistent object or file storage.",
sortOrder: 80,
definitionTypes: ["rvn-efs", "rvn-s3"],
},
{
givenId: "cluster",
name: "Cluster",
description: "For services that share container capacity, load balancers, and placement configuration.",
sortOrder: 90,
definitionTypes: ["rvn-ecs-cluster"],
},
{
givenId: "network",
name: "Network",
description: "For private subnets, internet access, service connectivity, and shared load balancers.",
sortOrder: 100,
definitionTypes: ["rvn-aws-alb", "rvn-aws-network"],
},
{
givenId: "domain",
name: "Domain",
description: "For custom domains, DNS records, and HTTPS certificates.",
sortOrder: 110,
definitionTypes: ["rvn-acm-certificate", "rvn-route53"],
},
{
givenId: "cdn",
name: "CDN",
description: "For serving images, JavaScript bundles, and downloads closer to users.",
sortOrder: 120,
definitionTypes: ["rvn-cloudfront"],
},
{
givenId: "security",
name: "Security",
description: "For service roles, deployment permissions, and least-privilege access.",
sortOrder: 130,
definitionTypes: ["rvn-aws-iam-policy", "rvn-aws-iam-role"],
},
{
givenId: "iac",
name: "IaC",
description: "For custom infrastructure that is not covered by a purpose-built module.",
sortOrder: 140,
definitionTypes: ["rvn-stack"],
},
];

const MODULE_CATEGORIES_BY_DEFINITION_TYPE = new Map<string, ModuleCategorySpec[]>();
for (const category of MODULE_CATEGORIES) {
for (const definitionType of category.definitionTypes) {
const categories = MODULE_CATEGORIES_BY_DEFINITION_TYPE.get(definitionType) ?? [];
categories.push(category);
MODULE_CATEGORIES_BY_DEFINITION_TYPE.set(definitionType, categories);
}
}

export function getModuleCategoriesForDefinitionType(
definitionType: string,
): readonly ModuleCategorySpec[] {
return MODULE_CATEGORIES_BY_DEFINITION_TYPE.get(definitionType) ?? [];
}
Loading
Loading