diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..c4a8e20 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,39 @@ +// Code generated by github.com/heetch/cue-schema/github/workflow/generate. DO NOT EDIT. +jobs: + test: + runs-on: ${{ matrix.platform }} + services: + kafka: + env: + KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092 + KAFKA_BROKER_ID: "1" + KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT + KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT + KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: "1" + KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 + image: confluentinc/cp-kafka:latest + steps: + - name: Install Go + uses: actions/setup-go@v1 + with: + go-version: ${{ matrix.go-version }} + - name: Module cache + uses: actions/cache@v1 + with: + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + path: ~/go/pkg/mod + restore-keys: ${{ runner.os }}-go- + - name: Checkout code + uses: actions/checkout@v1 + - name: Test + run: go test ./... + strategy: + matrix: + go-version: + - 1.13.x + platform: + - ubuntu-latest +name: Test +"on": +- push +- pull_request diff --git a/cue.mod/module.cue b/cue.mod/module.cue new file mode 100644 index 0000000..f8af9ce --- /dev/null +++ b/cue.mod/module.cue @@ -0,0 +1 @@ +module: "" diff --git a/cue.mod/pkg/github.com/heetch/cue-schema/github/cue.mod/module.cue b/cue.mod/pkg/github.com/heetch/cue-schema/github/cue.mod/module.cue new file mode 100644 index 0000000..d626ddc --- /dev/null +++ b/cue.mod/pkg/github.com/heetch/cue-schema/github/cue.mod/module.cue @@ -0,0 +1 @@ +module: "github.com/heetch/cue-schema/github" diff --git a/cue.mod/pkg/github.com/heetch/cue-schema/github/generate/generate-workflow.cue b/cue.mod/pkg/github.com/heetch/cue-schema/github/generate/generate-workflow.cue new file mode 100644 index 0000000..a1f9cc4 --- /dev/null +++ b/cue.mod/pkg/github.com/heetch/cue-schema/github/generate/generate-workflow.cue @@ -0,0 +1,19 @@ +package generate + +import ( + "tool/file" + "encoding/yaml" + "github.com/heetch/cue-schema/github/workflow" +) + +Workflow :: workflow + +command: generateworkflow: { + task: write: file.Create & { + filename: ".github/workflows/test.yaml" + contents: """ + # Code generated by github.com/heetch/cue-schema/github/workflow/generate. DO NOT EDIT. + \(yaml.Marshal(Workflow)) + """ + } +} diff --git a/cue.mod/pkg/github.com/heetch/cue-schema/github/workflow/event.cue b/cue.mod/pkg/github.com/heetch/cue-schema/github/workflow/event.cue new file mode 100644 index 0000000..252fa85 --- /dev/null +++ b/cue.mod/pkg/github.com/heetch/cue-schema/github/workflow/event.cue @@ -0,0 +1,217 @@ +package workflow + +Event :: + "check_run" | + "check_suite" | + "commit_comment" | + "create" | + "delete" | + "deployment" | + "deployment_status" | + "fork" | + "gollum" | + "issue_comment" | + "issues" | + "label" | + "member" | + "milestone" | + "page_build" | + "project" | + "project_card" | + "project_column" | + "public" | + "pull_request" | + "pull_request_review" | + "pull_request_review_comment" | + "push" | + "release" | + "repository_dispatch" | + "schedule" | + "status" | + "watch" + +EventConfig :: { + check_run?: null | { + type = + "created" | + "rerequested" | + "completed" | + "requested_action" + types?: [ ... type] + } + check_suite?: null | { + type = + "assigned" | + "unassigned" | + "labeled" | + "unlabeled" | + "opened" | + "edited" | + "closed" | + "reopened" | + "synchronize" | + "ready_for_review" | + "locked" | + "unlocked " | + "review_requested " | + "review_request_removed" + types?: [ ... type] + } + commit_comment?: null | {} + create?: null | {} + delete?: null | {} + deployment?: null | {} + deployment_status?: null | {} + fork?: null | {} + gollum?: null | {} + issue_comment?: null | { + type = + "created" | + "edited" | + "deleted" + types?: [ ... type] + } + issues?: null | { + type = + "opened" | + "edited" | + "deleted" | + "transferred" | + "pinned" | + "unpinned" | + "closed" | + "reopened" | + "assigned" | + "unassigned" | + "labeled" | + "unlabeled" | + "locked" | + "unlocked" | + "milestoned" | + "demilestoned" + types?: [ ... type] + } + label?: null | { + type = + "created" | + "edited" | + "deleted" + types?: [ ... type] + } + member?: null | { + type = + "added" | + "edited" | + "deleted" + types?: [ ... type] + } + milestone?: null | { + type = + "created" | + "closed" | + "opened" | + "edited" | + "deleted" + types?: [ ... type] + } + page_build?: null | {} + project?: null | { + type = + "created" | + "closed" | + "opened" | + "edited" | + "deleted" + types?: [ ... type] + } + project_card?: null | { + type = + "created" | + "moved" | + "converted" | + "edited" | + "deleted" + types?: [ ... type] + } + project_column?: null | { + type = + "created" | + "updated" | + "moved" | + "deleted" + types?: [ ... type] + } + public?: null | {} + pull_request?: null | { + PushPullEvent + type = + "assigned" | + "unassigned" | + "labeled" | + "unlabeled" | + "opened" | + "edited" | + "closed" | + "reopened" | + "synchronize" | + "ready_for_review" | + "locked" | + "unlocked " | + "review_requested " | + "review_request_removed" + types?: [ ... type] + } + pull_request_review?: null | { + type = + "submitted" | + "edited" | + "dismissed" + types?: [ ... type] + } + pull_request_review_comment?: null | { + type = + "created" | + "edited" | + "deleted" + types?: [ ... type] + } + push?: null | { + PushPullEvent + } + release?: null | { + type = + "published " | + "unpublished " | + "created " | + "edited " | + "deleted " | + "prereleased" + types? : [ ... type] + } + repository_dispatch?: null | {} + // schedule configures a workflow to run at specific UTC times using POSIX + // cron syntax. Scheduled workflows run on the latest commit on the + // default or base branch. + schedule?: null | [{ + // cron specifies the time schedule in cron syntax. + // See https://help.github.com/en/articles/events-that-trigger-workflows#scheduled-events + // TODO regexp for cron syntax + cron: string + }] + status?: null | {} + watch?: null | { + types?: [ "started"] + } +} + +PushPullEvent :: { + branches?: [... Glob] + tags?: [... Glob] + "branches-ignore"?: [... Glob] + "tags-ignore"?: [... Glob] + paths?: [... Glob] +} + +// Glob represents a wildcard pattern. +// See https://help.github.com/en/articles/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet +Glob :: string diff --git a/cue.mod/pkg/github.com/heetch/cue-schema/github/workflow/example/go/.github/workflows/test.yaml b/cue.mod/pkg/github.com/heetch/cue-schema/github/workflow/example/go/.github/workflows/test.yaml new file mode 100644 index 0000000..e0fc21f --- /dev/null +++ b/cue.mod/pkg/github.com/heetch/cue-schema/github/workflow/example/go/.github/workflows/test.yaml @@ -0,0 +1,44 @@ +// Code generated by github.com/heetch/cue-schema/github/workflow/generate. DO NOT EDIT. +jobs: + test: + runs-on: ${{ matrix.platform }} + services: + kafka: + env: + KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092 + KAFKA_BROKER_ID: "1" + KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT + KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT + KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: "1" + KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 + image: confluentinc/cp-kafka:latest + postgres: + env: + POSTGRES_DB: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_USER: postgres + image: postgres:10.8 + options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s + --health-retries 5 + ports: + - 5432:5432 + steps: + - name: Install Go + uses: actions/setup-go@v1 + with: + go-version: ${{ matrix.go-version }} + - name: Checkout code + uses: actions/checkout@v1 + - name: Test + run: go test ./... + strategy: + matrix: + go-version: + - v1.12.x + - v1.13.x + platform: + - ubuntu-latest +name: My CI caboodle +"on": +- push +- pull_request diff --git a/cue.mod/pkg/github.com/heetch/cue-schema/github/workflow/example/go/ci.yaml b/cue.mod/pkg/github.com/heetch/cue-schema/github/workflow/example/go/ci.yaml new file mode 100644 index 0000000..fb647b6 --- /dev/null +++ b/cue.mod/pkg/github.com/heetch/cue-schema/github/workflow/example/go/ci.yaml @@ -0,0 +1,42 @@ +jobs: + test: + runs-on: ${{ matrix.platform }} + services: + kafka: + env: + KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092 + KAFKA_BROKER_ID: "1" + KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT + KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT + KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: "1" + KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 + image: confluentinc/cp-kafka:latest + postgres: + env: + POSTGRES_DB: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_USER: postgres + image: postgres:10.8 + options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s + --health-retries 5 + ports: + - 5432:5432 + steps: + - name: Install Go + uses: actions/setup-go@v1 + with: + go-version: ${{ matrix.go-version }} + - name: Checkout code + uses: actions/checkout@v1 + - name: Test + run: go test ./... + strategy: + matrix: + go-version: + - go1.13.4 + platform: + - ubuntu-latest +name: My CI caboodle +"on": +- push +- pull_request diff --git a/cue.mod/pkg/github.com/heetch/cue-schema/github/workflow/example/go/go.cue b/cue.mod/pkg/github.com/heetch/cue-schema/github/workflow/example/go/go.cue new file mode 100644 index 0000000..6beeac1 --- /dev/null +++ b/cue.mod/pkg/github.com/heetch/cue-schema/github/workflow/example/go/go.cue @@ -0,0 +1,12 @@ +package go + +import ( + goworkflow "github.com/heetch/cue-schema/github/workflow/go:workflow" +) + +Workflow :: goworkflow +Workflow :: { + name: "My CI caboodle" + Versions :: ["v1.12", "v1.13"] + Services :: ["postgres", "kafka"] +} diff --git a/cue.mod/pkg/github.com/heetch/cue-schema/github/workflow/go/go.cue b/cue.mod/pkg/github.com/heetch/cue-schema/github/workflow/go/go.cue new file mode 100644 index 0000000..9598421 --- /dev/null +++ b/cue.mod/pkg/github.com/heetch/cue-schema/github/workflow/go/go.cue @@ -0,0 +1,97 @@ + +// Go-centric defaults for github actions. +// +// This defines a single test job with appropriate defaults. +// Override the Platforms, Versions, RunTest and Services definitions +// for easy modification of some parameters. +package workflow + +on: _ | *["push", "pull_request"] +name: _ | *"Test" +jobs: test: { + strategy: matrix: { + "go-version": _ | *[ "\(v).x" for v in Versions ] + platform: _ | *[ "\(p)-latest" for p in Platforms ] + } + "runs-on": "${{ matrix.platform }}" + steps: [{ + name: "Install Go" + uses: "actions/setup-go@v1" + with: "go-version": "${{ matrix.go-version }}" + }, { + name: "Module cache" + uses: "actions/cache@v1" + with: { + path: "~/go/pkg/mod" + key: "${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}" + "restore-keys": "${{ runner.os }}-go-" + } + }, { + name: "Checkout code" + uses: "actions/checkout@v1" + }, _ | *{ + name: "Test" + run: RunTest + }] +} + +// Include all named services. +for name in Services { + jobs: test: services: "\(name)": ServiceConfig[name] +} + +jobs: test: services: kafka?: _ | *{ + image: "confluentinc/cp-kafka:latest" + env: { + KAFKA_BROKER_ID: "1" + KAFKA_ZOOKEEPER_CONNECT: "zookeeper:2181" + KAFKA_ADVERTISED_LISTENERS: "PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092" + KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: "PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT" + KAFKA_INTER_BROKER_LISTENER_NAME: "PLAINTEXT" + KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: "1" + } +} + +// Platforms configures what platforms to run the tests on. +Platforms :: *["ubuntu"] | [ ... "ubuntu" | "macos" | "windows"] + +// Versions configures what Go versions to run the tests on. +// TODO regexp.Match("^1.[0-9]+$") +Versions :: *["1.13"] | [ ... string] + +// RunTest configures the command used to run the tests. +RunTest :: *"go test ./..." | string + +// Service configures which services to make available. +// The configuration the service with name N is taken from +// ServiceConfig[N] +Services :: [... string] + +// ServiceConfig holds the default configuration for services that +// can be started by naming them in Services. +ServiceConfig :: [_]: _ + +ServiceConfig :: kafka: { + image: "confluentinc/cp-kafka:latest" + env: { + KAFKA_BROKER_ID: "1" + KAFKA_ZOOKEEPER_CONNECT: "zookeeper:2181" + KAFKA_ADVERTISED_LISTENERS: "PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092" + KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: "PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT" + KAFKA_INTER_BROKER_LISTENER_NAME: "PLAINTEXT" + KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: "1" + } +} + +ServiceConfig :: postgres: { + env: { + POSTGRES_DB: "postgres" + POSTGRES_PASSWORD: "postgres" + POSTGRES_USER: "postgres" + } + image: "postgres:10.8" + options: "--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5" + ports: [ + "5432:5432", + ] +} diff --git a/cue.mod/pkg/github.com/heetch/cue-schema/github/workflow/workflow.cue b/cue.mod/pkg/github.com/heetch/cue-schema/github/workflow/workflow.cue new file mode 100644 index 0000000..320ca1f --- /dev/null +++ b/cue.mod/pkg/github.com/heetch/cue-schema/github/workflow/workflow.cue @@ -0,0 +1,97 @@ + +// Package workflow describes the contents of a file in the +// .github/workflows directory of a repository. +// +// This follows the API described here: +// https://help.github.com/en/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions +package workflow + +// TODO cross-verify against https://github.com/SchemaStore/schemastore/blob/master/src/schemas/json/github-workflow.json + +import "regexp" + +// name holds the name of your workflow. GitHub displays the +// names of your workflows on your repository's actions page. If +// you omit this field, GitHub sets the name to the workflow's +// filename. +name?: string + +// On describes the event or events that trigger the workflow. +on: Event | [... Event] | EventConfig + +env?: Env +jobs: { + // TODO must start with a letter or _ and contain only alphanumeric characters, -, or _. + [_]: Job +} + +// Job represents one of the jobs to do as part of the action. +Job :: { + name?: string + // TODO restrict JobID to names mentioned in the workflow jobs? + needs?: JobID | [...JobID] + "runs-on"?: string | [string, ...string] + env?: Env + if?: Condition + steps?: [... JobStep] + "timeout-minutes"?: number + container?: { + image?: string + env?: Env + ports?: [ ... int] + volumes?: [ ... string] + options?: _ // TODO more specific type here + } + strategy?: { + matrix: [_]: [ ...] + "fail-fast"?: bool + "max-parallel"?: int & >0 + } + services: { + [_]: Service + } +} + +Service :: { + image: string + env?: Env + ports?: [... string] + volumes?: [ ... string] + options?: _ // TODO more specific type here +} + +JobStep :: { + id?: string + if?: Condition + name?: string + uses?: string + run?: string + "working-directory"?: string + shell?: + "bash" | + "pwsh" | + "python" | + "sh" | + "cmd" | + "powershell" | + regexp.Match(#"\{0\}"#) + + // with holds a map of the input parameters defined by the action. + // Each input parameter is a key/value pair. Input parameters are + // set as environment variables. The variable is prefixed with INPUT_ + // and converted to upper case. + with?: [_]: string + env?: Env + "continue-on-error"?: bool + "timeout-minutes"?: number +} + +// JobID represents one the of jobs specified in Workflow. +JobID :: string + +// Condition represents a condition to evaluate. +// TODO link to syntax. +Condition :: string + +// Env represents a set of environment variables and their values. +Env :: [_]: string diff --git a/github-action_tool.cue b/github-action_tool.cue new file mode 100644 index 0000000..b8d1a4a --- /dev/null +++ b/github-action_tool.cue @@ -0,0 +1,25 @@ +package kafkatestCI + +import ( + "encoding/yaml" + "tool/file" + + "github.com/heetch/cue-schema/github/workflow/go:workflow" +) + +// To generate the github actions workflow file, run: +// +// cue generateworkflow + +Workflow :: workflow +Workflow :: Services :: ["kafka"] + +command: generateworkflow: { + task: write: file.Create & { + filename: ".github/workflows/test.yaml" + contents: """ + // Code generated by github.com/heetch/cue-schema/github/workflow/generate. DO NOT EDIT. + \(yaml.Marshal(Workflow)) + """ + } +}