Skip to content

Commit

Permalink
Set up build (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
amrc-benmorrow authored Oct 17, 2024
2 parents ca3f1bd + 28a832e commit 882e048
Show file tree
Hide file tree
Showing 8 changed files with 226 additions and 3 deletions.
58 changes: 58 additions & 0 deletions .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Build & Release schemas

env:
BASE_JS_VERSION: v3.0.0
IMAGE_NAME: ghcr.io/amrc-factoryplus/acs-schemas

on:
release:
types: [ published ]

jobs:
build-x86-js:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Cosign
uses: sigstore/[email protected]
- name: Setup build
uses: docker/setup-buildx-action@v3
- name: Login to registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
uses: docker/metadata-action@v5
id: meta
with:
images: ${{ env.IMAGE_NAME }}
- name: Build
uses: docker/build-push-action@v5
id: build-and-push
with:
context: .
push: true
tags: ${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
tag=${{ steps.meta.outputs.version }}
revision=${{ steps.meta.outputs.version }} (${{ github.sha }})
base_version=${{ env.BASE_JS_VERSION }}
- name: Sign image
shell: sh
env:
COSIGN_EXPERIMENTAL: "true"
# This step uses the identity token to provision an ephemeral certificate
# against the sigstore community Fulcio instance.
run: echo "${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}" | xargs -I {} cosign sign --yes {}@${{ steps.build-and-push.outputs.digest }}
2 changes: 1 addition & 1 deletion .github/workflows/validate.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ jobs:
container: node:16
steps:
- uses: actions/checkout@v3
- run: cd validate && npm install --save=false && node validate.js
- run: cd deploy && npm install --save=false && node bin/lint.js
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
node_modules/
.env
package-lock.json
config.mk

*instances/
.DS_Store
.DS_Store
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ ARG base_prefix=ghcr.io/amrc-factoryplus/acs-base

FROM ${base_prefix}-js-build:${base_version} AS build
ARG revision=unknown
ARG source_repo=https://github.com/amrc-factoryplus/acs-schemas

USER root
RUN sh -x <<'SHELL'
Expand Down
64 changes: 64 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Makefile for acs-schemas
# This is a POSIX Makefile. Please avoid gmake extensions.
# On Windows try https://frippery.org/busybox.

-include config.mk

git.tag!=git describe --tags --abbrev=0
git.sha!=git rev-parse --verify HEAD

version?=${git.tag}
registry?=ghcr.io/amrc-factoryplus
repo?=acs-schemas
suffix?=

tag=${version}${suffix}
image=${registry}/${repo}:${tag}

platform?= linux/amd64

build_args+= --build-arg revision="${git.tag} (${git.sha})"
build_args+= --build-arg tag="${tag}"

.PHONY: all build pull run

all: build

build: git.prepare
docker buildx build --push --platform "${platform}" -t "${image}" ${build_args} .

pull:
docker pull "${image}"

run: pull
docker run -ti --rm "${image}" /bin/sh

.PHONY: lint

build: lint

lint:
cd deploy && node bin/lint.js

.PHONY: git.prepare git.check-committed git.pull amend

git.prepare:
@:

ifndef git.allow_dirty
git.prepare: git.check-committed
endif

ifdef git.pull
git.prepare: git.pull
endif

git.check-committed:
[ -z "$$(git status --porcelain)" ] || (git status; exit 1)

git.pull:
git pull --ff-only

amend:
git commit --amend -C HEAD -a

3 changes: 3 additions & 0 deletions deploy/bin/find-schemas.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import Walk from "@root/walk";
import git from "isomorphic-git";
import YAML from "yaml";

const source = process.env.source_repo;

const schemas = "../schemas";
const path_rx = RegExp(`^${schemas}/([\\w/_]+)-v(\\d+).yaml$`);

Expand Down Expand Up @@ -52,6 +54,7 @@ for (const [path, meta] of yamls.entries()) {
...meta,
created: changes.at(-1),
modified: changes.at(0),
source,
},
schema,
};
Expand Down
93 changes: 93 additions & 0 deletions deploy/bin/lint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/* Validate JSON schemas */

import $fsp from "fs/promises";
import $path from "path";
import $process from "process";

import Ajv2020 from "ajv/dist/2020.js";
import formats from "ajv-formats";
import Walk from "@root/walk";
import YAML from "yaml";

const path_rx = /^([\w/_]+)-v(\d+).yaml$/;
const id_rx = /^urn:uuid:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;

const schemas = new Map();
const paths = new Map();

let exit = 0;
function error (...args) {
console.log(...args);
exit = 1;
}

function loadYAML (path) {
return $fsp.readFile(path, { encoding: "utf-8" })
.then(YAML.parse);
}

function schemaWalker (schemas) {
const cwd = $path.resolve();

return async (err, path, dirent) => {
if (err) throw err;
const rel = path.replaceAll("\\", "/")
.replace("../schemas/", "");

if (dirent.isDirectory()) return;
if (!rel.endsWith(".yaml")) return;

if (!path_rx.test(rel))
error("Bad schema filename: %s", rel)

const schema = await loadYAML(path)
.catch(err => {
error("YAML error in %s: %s",
rel, err.message);
});
if (schema == null) return;

if (!(typeof schema == "object" && "$id" in schema)) {
error("Not a schema: %s", rel);
return;
}

const id = schema.$id;
if (!id_rx.test(id)) {
error("Incorrect $id format in %s", rel);
return;
}

schemas.set(id, schema);
paths.set(id, rel);
};
}

function loadSchema (id) {
if (!schemas.has(id))
throw `No schema with id ${id}`;
return schemas.get(id);
}

const ajv = new Ajv2020({
loadSchema,
addUsedSchema: false,
/* XXX We may want to revist these exceptions. Currently they are
* violated everywhere. */
strictTypes: false,
allowMatchingProperties: true,
});
formats(ajv);

await Walk.walk("../schemas", schemaWalker(schemas));

for (const sch of schemas.values()) {
//console.log(`Checking ${sch.$id}`);
await ajv.compileAsync(sch)
.catch(err => {
error("Error in %s: %s",
paths.get(sch.$id), err);
});
}

$process.exit(exit);
5 changes: 4 additions & 1 deletion deploy/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
"dependencies": {
"@amrc-factoryplus/service-client": "^1.3.6",
"@root/walk": "^1.1.0",
"isomorphic-git": "^1.27.1"
"ajv": "^8.17.1",
"ajv-formats": "^3.0.1",
"isomorphic-git": "^1.27.1",
"yaml": "^2.6.0"
}
}

0 comments on commit 882e048

Please sign in to comment.