Skip to content

Commit

Permalink
chore(k8s): add cd via timoni+flux
Browse files Browse the repository at this point in the history
  • Loading branch information
kjubybot committed Feb 7, 2025
1 parent b4cb7e4 commit 867c636
Show file tree
Hide file tree
Showing 215 changed files with 37,476 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,8 @@ jobs:
# run: make test-code-checkers
# env:
# MIX_ENV: test

build-package:
uses: ./.github/workflows/package.yaml
with:
is-pr: false
50 changes: 50 additions & 0 deletions .github/workflows/package.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Build package

on:
workflow_call:
inputs:
is-pr:
description: Whether it's a pr
type: boolean
required: true
jobs:
build-package:
permissions:
contents: read
packages: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Timoni
uses: stefanprodan/timoni/actions/setup@main
- name: Setup Flux
uses: fluxcd/flux2/action@main

- name: Build bundle
env:
BUNDLE_PATH: k8s/timoni/
run: |
mkdir ${{ runner.temp }}/timoni
timoni bundle build \
-f ${BUNDLE_PATH}bundle.cue \
-f ${BUNDLE_PATH}runners.cue \
-f ${BUNDLE_PATH}values.cue > ${{ runner.temp }}/timoni/build.yaml
- name: Preapre tag
if: ${{ inputs.is-pr }}
run: |
tag=$(echo ${{ github.head_ref }} | tr '/' '-')
echo "tag=${tag}" >> "${GITHUB_ENV}"
- name: Prepare tag
if: ${{ ! inputs.is-pr }}
run: echo "tag=${{ github.ref_name }}" >> "${GITHUB_ENV}"

- name: Push artifact
run: |
flux push artifact \
--creds ${{ github.actor }}:${{ secrets.GITHUB_TOKEN }} \
-f ${{ runner.temp }}/timoni \
--source ${{ github.repositoryUrl }} \
--revision ${{ inputs.tag }}@sha1:${{ github.sha }} \
oci://ghcr.io/${{ github.repository }}-manifests:${tag}
5 changes: 5 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,8 @@ jobs:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./services/app/assp/codebattle/cover/excoveralls.json
fail_ci_if_error: false

build-package:
uses: ./.github/workflows/package.yaml
with:
is-pr: true
19 changes: 19 additions & 0 deletions k8s/flux.cue
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
bundle: {
apiVersion: "v1alpha1"
name: "codebattle"
instances: "codebattle": {
module: url: "oci://ghcr.io/stefanprodan/modules/flux-oci-sync"
namespace: "flux-system"
values: {
artifact: {
url: "oci://ghcr.io/hexlet-codebattle/codebattle-manifests"
tag: "master"
}
auth: credentials: {
username: string @timoni(runtime:string:GITHUB_USERNAME)
password: string @timoni(runtime:string:GITHUB_TOKEN)
}
}
}

}
35 changes: 35 additions & 0 deletions k8s/timoni/bundle.cue
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#RunnerConfig: {
image: string
version: string
lang: string
replicas: uint
}

runners: [string]: #RunnerConfig
codebattleValues: {}

bundle: {
apiVersion: "v1alpha1"
name: "codebattle"
instances: {
codebattle: {
module: url: "file://codebattle"
namespace: "codebattle"
values: codebattleValues
}
for runner in runners {
"runner-\(runner.lang)": {
module: url: "file://runner"
namespace: "codebattle"
values: {
registry: "docker.io"
image: {
repository: "\(registry)/\(runner.image)"
tag: runner.version
}
replicas: runner.replicas
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Code generated by cue get go. DO NOT EDIT.

//cue:generate cue get go k8s.io/api/admission/v1

package v1

#GroupName: "admission.k8s.io"
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
// Code generated by cue get go. DO NOT EDIT.

//cue:generate cue get go k8s.io/api/admission/v1

package v1

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
authenticationv1 "k8s.io/api/authentication/v1"
"k8s.io/apimachinery/pkg/runtime"
)

// AdmissionReview describes an admission review request/response.
#AdmissionReview: {
metav1.#TypeMeta

// Request describes the attributes for the admission request.
// +optional
request?: null | #AdmissionRequest @go(Request,*AdmissionRequest) @protobuf(1,bytes,opt)

// Response describes the attributes for the admission response.
// +optional
response?: null | #AdmissionResponse @go(Response,*AdmissionResponse) @protobuf(2,bytes,opt)
}

// AdmissionRequest describes the admission.Attributes for the admission request.
#AdmissionRequest: {
// UID is an identifier for the individual request/response. It allows us to distinguish instances of requests which are
// otherwise identical (parallel requests, requests when earlier requests did not modify etc)
// The UID is meant to track the round trip (request/response) between the KAS and the WebHook, not the user request.
// It is suitable for correlating log entries between the webhook and apiserver, for either auditing or debugging.
uid: types.#UID @go(UID) @protobuf(1,bytes,opt)

// Kind is the fully-qualified type of object being submitted (for example, v1.Pod or autoscaling.v1.Scale)
kind: metav1.#GroupVersionKind @go(Kind) @protobuf(2,bytes,opt)

// Resource is the fully-qualified resource being requested (for example, v1.pods)
resource: metav1.#GroupVersionResource @go(Resource) @protobuf(3,bytes,opt)

// SubResource is the subresource being requested, if any (for example, "status" or "scale")
// +optional
subResource?: string @go(SubResource) @protobuf(4,bytes,opt)

// RequestKind is the fully-qualified type of the original API request (for example, v1.Pod or autoscaling.v1.Scale).
// If this is specified and differs from the value in "kind", an equivalent match and conversion was performed.
//
// For example, if deployments can be modified via apps/v1 and apps/v1beta1, and a webhook registered a rule of
// `apiGroups:["apps"], apiVersions:["v1"], resources: ["deployments"]` and `matchPolicy: Equivalent`,
// an API request to apps/v1beta1 deployments would be converted and sent to the webhook
// with `kind: {group:"apps", version:"v1", kind:"Deployment"}` (matching the rule the webhook registered for),
// and `requestKind: {group:"apps", version:"v1beta1", kind:"Deployment"}` (indicating the kind of the original API request).
//
// See documentation for the "matchPolicy" field in the webhook configuration type for more details.
// +optional
requestKind?: null | metav1.#GroupVersionKind @go(RequestKind,*metav1.GroupVersionKind) @protobuf(13,bytes,opt)

// RequestResource is the fully-qualified resource of the original API request (for example, v1.pods).
// If this is specified and differs from the value in "resource", an equivalent match and conversion was performed.
//
// For example, if deployments can be modified via apps/v1 and apps/v1beta1, and a webhook registered a rule of
// `apiGroups:["apps"], apiVersions:["v1"], resources: ["deployments"]` and `matchPolicy: Equivalent`,
// an API request to apps/v1beta1 deployments would be converted and sent to the webhook
// with `resource: {group:"apps", version:"v1", resource:"deployments"}` (matching the resource the webhook registered for),
// and `requestResource: {group:"apps", version:"v1beta1", resource:"deployments"}` (indicating the resource of the original API request).
//
// See documentation for the "matchPolicy" field in the webhook configuration type.
// +optional
requestResource?: null | metav1.#GroupVersionResource @go(RequestResource,*metav1.GroupVersionResource) @protobuf(14,bytes,opt)

// RequestSubResource is the name of the subresource of the original API request, if any (for example, "status" or "scale")
// If this is specified and differs from the value in "subResource", an equivalent match and conversion was performed.
// See documentation for the "matchPolicy" field in the webhook configuration type.
// +optional
requestSubResource?: string @go(RequestSubResource) @protobuf(15,bytes,opt)

// Name is the name of the object as presented in the request. On a CREATE operation, the client may omit name and
// rely on the server to generate the name. If that is the case, this field will contain an empty string.
// +optional
name?: string @go(Name) @protobuf(5,bytes,opt)

// Namespace is the namespace associated with the request (if any).
// +optional
namespace?: string @go(Namespace) @protobuf(6,bytes,opt)

// Operation is the operation being performed. This may be different than the operation
// requested. e.g. a patch can result in either a CREATE or UPDATE Operation.
operation: #Operation @go(Operation) @protobuf(7,bytes,opt)

// UserInfo is information about the requesting user
userInfo: authenticationv1.#UserInfo @go(UserInfo) @protobuf(8,bytes,opt)

// Object is the object from the incoming request.
// +optional
object?: runtime.#RawExtension @go(Object) @protobuf(9,bytes,opt)

// OldObject is the existing object. Only populated for DELETE and UPDATE requests.
// +optional
oldObject?: runtime.#RawExtension @go(OldObject) @protobuf(10,bytes,opt)

// DryRun indicates that modifications will definitely not be persisted for this request.
// Defaults to false.
// +optional
dryRun?: null | bool @go(DryRun,*bool) @protobuf(11,varint,opt)

// Options is the operation option structure of the operation being performed.
// e.g. `meta.k8s.io/v1.DeleteOptions` or `meta.k8s.io/v1.CreateOptions`. This may be
// different than the options the caller provided. e.g. for a patch request the performed
// Operation might be a CREATE, in which case the Options will a
// `meta.k8s.io/v1.CreateOptions` even though the caller provided `meta.k8s.io/v1.PatchOptions`.
// +optional
options?: runtime.#RawExtension @go(Options) @protobuf(12,bytes,opt)
}

// AdmissionResponse describes an admission response.
#AdmissionResponse: {
// UID is an identifier for the individual request/response.
// This must be copied over from the corresponding AdmissionRequest.
uid: types.#UID @go(UID) @protobuf(1,bytes,opt)

// Allowed indicates whether or not the admission request was permitted.
allowed: bool @go(Allowed) @protobuf(2,varint,opt)

// Result contains extra details into why an admission request was denied.
// This field IS NOT consulted in any way if "Allowed" is "true".
// +optional
status?: null | metav1.#Status @go(Result,*metav1.Status) @protobuf(3,bytes,opt)

// The patch body. Currently we only support "JSONPatch" which implements RFC 6902.
// +optional
patch?: bytes @go(Patch,[]byte) @protobuf(4,bytes,opt)

// The type of Patch. Currently we only allow "JSONPatch".
// +optional
patchType?: null | #PatchType @go(PatchType,*PatchType) @protobuf(5,bytes,opt)

// AuditAnnotations is an unstructured key value map set by remote admission controller (e.g. error=image-blacklisted).
// MutatingAdmissionWebhook and ValidatingAdmissionWebhook admission controller will prefix the keys with
// admission webhook name (e.g. imagepolicy.example.com/error=image-blacklisted). AuditAnnotations will be provided by
// the admission webhook to add additional context to the audit log for this request.
// +optional
auditAnnotations?: {[string]: string} @go(AuditAnnotations,map[string]string) @protobuf(6,bytes,opt)

// warnings is a list of warning messages to return to the requesting API client.
// Warning messages describe a problem the client making the API request should correct or be aware of.
// Limit warnings to 120 characters if possible.
// Warnings over 256 characters and large numbers of warnings may be truncated.
// +optional
warnings?: [...string] @go(Warnings,[]string) @protobuf(7,bytes,rep)
}

// PatchType is the type of patch being used to represent the mutated object
#PatchType: string // #enumPatchType

#enumPatchType:
#PatchTypeJSONPatch

#PatchTypeJSONPatch: #PatchType & "JSONPatch"

// Operation is the type of resource operation being checked for admission control
#Operation: string // #enumOperation

#enumOperation:
#Create |
#Update |
#Delete |
#Connect

#Create: #Operation & "CREATE"
#Update: #Operation & "UPDATE"
#Delete: #Operation & "DELETE"
#Connect: #Operation & "CONNECT"
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Code generated by cue get go. DO NOT EDIT.

//cue:generate cue get go k8s.io/api/admissionregistration/v1

// Package v1 is the v1 version of the API.
// AdmissionConfiguration and AdmissionPluginConfiguration are legacy static admission plugin configuration
// MutatingWebhookConfiguration and ValidatingWebhookConfiguration are for the
// new dynamic admission controller configuration.
package v1
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Code generated by cue get go. DO NOT EDIT.

//cue:generate cue get go k8s.io/api/admissionregistration/v1

package v1

#GroupName: "admissionregistration.k8s.io"
Loading

0 comments on commit 867c636

Please sign in to comment.