Moda components setup (#53563)
Co-authored-by: moda-bot[bot] <56174108+moda-bot[bot]@users.noreply.github.com> Co-authored-by: Kevin Heis <heiskr@users.noreply.github.com> Co-authored-by: Rachael Sewell <rachmari@github.com>
This commit is contained in:
13
.github/dependabot.yml
vendored
13
.github/dependabot.yml
vendored
@@ -1,4 +1,10 @@
|
|||||||
version: 2
|
version: 2
|
||||||
|
registries:
|
||||||
|
ghcr: # Define access for a private registry
|
||||||
|
type: docker-registry
|
||||||
|
url: ghcr.io
|
||||||
|
username: PAT
|
||||||
|
password: ${{secrets.CONTAINER_BUILDER_TOKEN}}
|
||||||
updates:
|
updates:
|
||||||
- package-ecosystem: npm
|
- package-ecosystem: npm
|
||||||
directory: '/'
|
directory: '/'
|
||||||
@@ -23,11 +29,18 @@ updates:
|
|||||||
- dependency-name: '*'
|
- dependency-name: '*'
|
||||||
update-types:
|
update-types:
|
||||||
['version-update:semver-patch', 'version-update:semver-minor']
|
['version-update:semver-patch', 'version-update:semver-minor']
|
||||||
|
- dependency-name: 'github/internal-actions'
|
||||||
|
|
||||||
- package-ecosystem: 'docker'
|
- package-ecosystem: 'docker'
|
||||||
|
registries:
|
||||||
|
- ghcr
|
||||||
directory: '/'
|
directory: '/'
|
||||||
schedule:
|
schedule:
|
||||||
interval: weekly
|
interval: weekly
|
||||||
day: thursday
|
day: thursday
|
||||||
|
groups:
|
||||||
|
baseImages:
|
||||||
|
patterns:
|
||||||
|
- '*'
|
||||||
ignore:
|
ignore:
|
||||||
- dependency-name: 'node'
|
- dependency-name: 'node'
|
||||||
|
|||||||
65
.github/workflows/moda-ci.yaml
vendored
Normal file
65
.github/workflows/moda-ci.yaml
vendored
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
name: docs-internal Moda CI
|
||||||
|
|
||||||
|
# More info on CI actions setup can be found here:
|
||||||
|
# https://github.com/github/ops/blob/master/docs/playbooks/build-systems/moving-moda-apps-from-bp-to-actions.md
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches-ignore:
|
||||||
|
- 'gh-readonly-queue/**'
|
||||||
|
merge_group:
|
||||||
|
types: [checks_requested]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
moda-config-bundle:
|
||||||
|
if: ${{ github.repository == 'github/docs-internal' }}
|
||||||
|
name: ${{ matrix.ci_job.job }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
ci_job: [{ 'job': 'docs-internal-moda-config-bundle' }]
|
||||||
|
uses: github/internal-actions/.github/workflows/moda.yml@main
|
||||||
|
with:
|
||||||
|
ci-formatted-job-name: ${{ matrix.ci_job.job }}
|
||||||
|
vault-keys: ${{ vars.VAULT_KEYS }}
|
||||||
|
secrets:
|
||||||
|
dx-bot-token: ${{ secrets.INTERNAL_ACTIONS_DX_BOT_ACCOUNT_TOKEN }}
|
||||||
|
datadog-api-key: ${{ secrets.DATADOG_API_KEY }}
|
||||||
|
|
||||||
|
docker-image:
|
||||||
|
if: ${{ github.repository == 'github/docs-internal' }}
|
||||||
|
name: ${{ matrix.ci_job.job }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
ci_job: [{ 'job': 'docs-internal-docker-image' }]
|
||||||
|
uses: github/internal-actions/.github/workflows/kube.yml@main
|
||||||
|
with:
|
||||||
|
ci-formatted-job-name: ${{ matrix.ci_job.job }}
|
||||||
|
vault-keys: ${{ vars.VAULT_KEYS }}
|
||||||
|
secrets:
|
||||||
|
dx-bot-token: ${{ secrets.INTERNAL_ACTIONS_DX_BOT_ACCOUNT_TOKEN }}
|
||||||
|
datadog-api-key: ${{ secrets.DATADOG_API_KEY }}
|
||||||
|
|
||||||
|
docker-security:
|
||||||
|
if: ${{ github.repository == 'github/docs-internal' }}
|
||||||
|
name: ${{ matrix.ci_job.job }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
ci_job: [{ 'job': 'docs-internal-docker-security' }]
|
||||||
|
uses: github/internal-actions/.github/workflows/docker_security.yml@main
|
||||||
|
with:
|
||||||
|
ci-formatted-job-name: ${{ matrix.ci_job.job }}
|
||||||
|
vault-keys: ${{ vars.VAULT_KEYS }}
|
||||||
|
secrets:
|
||||||
|
dx-bot-token: ${{ secrets.INTERNAL_ACTIONS_DX_BOT_ACCOUNT_TOKEN }}
|
||||||
|
datadog-api-key: ${{ secrets.DATADOG_API_KEY }}
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
actions: read
|
||||||
|
checks: read
|
||||||
|
contents: read
|
||||||
|
statuses: read
|
||||||
|
id-token: write
|
||||||
@@ -10,6 +10,9 @@ FROM node:22-alpine@sha256:c13b26e7e602ef2f1074aef304ce6e9b7dd284c419b35d89fcf3c
|
|||||||
# This directory is owned by the node user
|
# This directory is owned by the node user
|
||||||
ARG APP_HOME=/home/node/app
|
ARG APP_HOME=/home/node/app
|
||||||
|
|
||||||
|
# Make sure there's a translations directory available to not error the COPY command
|
||||||
|
RUN mkdir -p translations && chown -R node:node translations
|
||||||
|
|
||||||
# Make sure we don't run anything as the root user
|
# Make sure we don't run anything as the root user
|
||||||
USER node
|
USER node
|
||||||
|
|
||||||
@@ -109,4 +112,4 @@ FROM preview AS production
|
|||||||
ENV ENABLED_LANGUAGES "en,zh,es,pt,ru,ja,fr,de,ko"
|
ENV ENABLED_LANGUAGES "en,zh,es,pt,ru,ja,fr,de,ko"
|
||||||
|
|
||||||
# Copy in all translations
|
# Copy in all translations
|
||||||
COPY --chown=node:node translations ./translations
|
COPY --chown=node:node --from=base translations ./translations
|
||||||
|
|||||||
53
config/kubernetes/production/deployments/webapp.yaml
Normal file
53
config/kubernetes/production/deployments/webapp.yaml
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: webapp
|
||||||
|
spec:
|
||||||
|
replicas: 2
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: webapp
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: webapp
|
||||||
|
annotations:
|
||||||
|
# If you emit structured logs, you can specify a parser to use so your logs are parsed
|
||||||
|
# properly and are much nicer to query in splunk. For more details, see
|
||||||
|
# https://thehub.github.com/engineering/development-and-ops/observability/logging/fluent-bit/
|
||||||
|
# fluentbit.io/parser: logfmt
|
||||||
|
spec:
|
||||||
|
dnsPolicy: Default
|
||||||
|
containers:
|
||||||
|
- name: webapp
|
||||||
|
image: docs-internal
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 4000m
|
||||||
|
memory: 5Gi
|
||||||
|
limits:
|
||||||
|
cpu: 4000m
|
||||||
|
memory: 14Gi
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 4000
|
||||||
|
protocol: TCP
|
||||||
|
envFrom:
|
||||||
|
- secretRef:
|
||||||
|
name: vault-secrets
|
||||||
|
- configMapRef:
|
||||||
|
name: kube-cluster-metadata
|
||||||
|
# Zero-downtime deploys
|
||||||
|
# https://thehub.github.com/engineering/products-and-services/internal/moda/feature-documentation/pod-lifecycle/#required-prestop-hook
|
||||||
|
# https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks
|
||||||
|
lifecycle:
|
||||||
|
preStop:
|
||||||
|
exec:
|
||||||
|
command: ['sleep', '5']
|
||||||
|
readinessProbe:
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
httpGet:
|
||||||
|
# WARNING: This should be updated to a meaningful endpoint for your application which will return a 200 once the app is fully started.
|
||||||
|
# See: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-readiness-probes
|
||||||
|
path: /healthz
|
||||||
|
port: http
|
||||||
23
config/kubernetes/production/services/webapp.yaml
Normal file
23
config/kubernetes/production/services/webapp.yaml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: webapp
|
||||||
|
labels:
|
||||||
|
service: webapp
|
||||||
|
annotations:
|
||||||
|
moda.github.net/domain-name: 'docs-internal.github.com'
|
||||||
|
moda.github.net/dns-registration-enabled: 'false'
|
||||||
|
moda.github.net/load-balancer-type:
|
||||||
|
public-external-http
|
||||||
|
# moda.github.net/allowed-ips: '23.235.32.0/20,43.249.72.0/22,103.244.50.0/24,103.245.222.0/23,103.245.224.0/24,104.156.80.0/20,140.248.64.0/18,140.248.128.0/17,146.75.0.0/17,151.101.0.0/16,157.52.64.0/18,167.82.0.0/17,167.82.128.0/20,167.82.160.0/20,167.82.224.0/20,172.111.64.0/18,185.31.16.0/22,199.27.72.0/21,199.232.0.0/1'
|
||||||
|
# ipv6 addresses not included
|
||||||
|
# curl -i "https://api.fastly.com/public-ip-list"
|
||||||
|
spec:
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 4000
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: http
|
||||||
|
selector:
|
||||||
|
app: webapp
|
||||||
|
type: LoadBalancer
|
||||||
13
config/moda/deployment.yaml
Normal file
13
config/moda/deployment.yaml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
required_builds:
|
||||||
|
- docs-internal-moda-config-bundle / docs-internal-moda-config-bundle
|
||||||
|
- docs-internal-docker-image / docs-internal-docker-image
|
||||||
|
- docs-internal-docker-security / docs-internal-docker-security
|
||||||
|
environments:
|
||||||
|
- name: production
|
||||||
|
auto_deploy: true
|
||||||
|
cluster_selector:
|
||||||
|
profile: general
|
||||||
|
region: iad
|
||||||
|
notifications:
|
||||||
|
slack_channels:
|
||||||
|
- '#docs-ops'
|
||||||
22
ownership.yaml
Normal file
22
ownership.yaml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
version: 1
|
||||||
|
ownership:
|
||||||
|
- team: github/docs-engineering
|
||||||
|
repo: https://github.com/github/docs-internal
|
||||||
|
name: docs-internal
|
||||||
|
kind: moda
|
||||||
|
long_name: Docs on Moda
|
||||||
|
description: Please use <https://catalog.githubapp.com/services/docs> instead.
|
||||||
|
exec_sponsor: nerdneha
|
||||||
|
product_manager: docs-bot
|
||||||
|
qos: best_effort
|
||||||
|
tier: 2
|
||||||
|
sev1:
|
||||||
|
pagerduty: https://github.pagerduty.com/escalation_policies#PN57VQ1
|
||||||
|
tta: 30m
|
||||||
|
sev2:
|
||||||
|
issue: https://github.com/github/docs-engineering/issues
|
||||||
|
tta: 1d
|
||||||
|
sev3:
|
||||||
|
issue: https://github.com/github/docs-engineering/issues
|
||||||
|
tta: 1w
|
||||||
@@ -27,6 +27,7 @@ const workflowsDir = path.join(__dirname, '../../../.github/workflows')
|
|||||||
const workflows: WorkflowMeta[] = fs
|
const workflows: WorkflowMeta[] = fs
|
||||||
.readdirSync(workflowsDir)
|
.readdirSync(workflowsDir)
|
||||||
.filter((filename) => filename.endsWith('.yml') || filename.endsWith('.yaml'))
|
.filter((filename) => filename.endsWith('.yml') || filename.endsWith('.yaml'))
|
||||||
|
.filter((filename) => filename !== 'moda-ci.yaml') // Skip moda-ci
|
||||||
.map((filename) => {
|
.map((filename) => {
|
||||||
const fullpath = path.join(workflowsDir, filename)
|
const fullpath = path.join(workflowsDir, filename)
|
||||||
const data = yaml.load(fs.readFileSync(fullpath, 'utf8')) as WorkflowMeta['data']
|
const data = yaml.load(fs.readFileSync(fullpath, 'utf8')) as WorkflowMeta['data']
|
||||||
|
|||||||
Reference in New Issue
Block a user