Skip to content
This repository was archived by the owner on Jun 26, 2026. It is now read-only.

Commit dae58b7

Browse files
twoGiantsclaude
andcommitted
ci: add GitHub Actions CI/CD pipeline
Add single workflow (ci.yml) that runs lint, build, and test on pull requests, then builds and publishes a container image to GHCR on master merge. Follows knative/func patterns: top-level permissions, concurrency groups, version pinning. Fix ESLint config by removing redundant rule spreads that re-enabled the base no-unused-vars rule over the TypeScript version. Add Jest globals for test files. Downgrade @console/pluginAPI shared dep to >=4.19.0. Restructure README: move deployment section to the top with OCP 4.19 prerequisite and GHCR registry link. Add separate prerequisites for deployment and development sections. Add hack/next-plan-number.sh for deterministic plan numbering based on remote PR count. Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 47a2c5c commit dae58b7

12 files changed

Lines changed: 456 additions & 54 deletions

File tree

.github/workflows/ci.yml

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
name: CI
2+
3+
permissions:
4+
id-token: write # Required for signing
5+
contents: read
6+
packages: write
7+
attestations: write
8+
9+
on:
10+
push:
11+
branches:
12+
- master
13+
pull_request:
14+
branches:
15+
- master
16+
17+
concurrency:
18+
group: ${{ github.workflow }}-${{ github.ref }}
19+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
20+
21+
jobs:
22+
# --------
23+
# CHECKS
24+
# --------
25+
checks:
26+
name: Lint and Test
27+
runs-on: ubuntu-latest
28+
timeout-minutes: 15
29+
steps:
30+
- uses: actions/checkout@v4
31+
32+
- name: Setup Node.js
33+
uses: actions/setup-node@v4
34+
with:
35+
node-version: "22"
36+
cache: yarn
37+
38+
- name: Enable Corepack
39+
run: corepack enable
40+
41+
- name: Install Dependencies
42+
run: yarn install --immutable
43+
44+
- name: Lint
45+
run: yarn lint
46+
47+
- name: Test
48+
run: yarn test
49+
50+
# -----------
51+
# BUILD IMAGE
52+
# -----------
53+
# Multi-arch and attestation are required for OCP.
54+
build-image:
55+
name: Build Image
56+
needs: checks
57+
runs-on: ubuntu-latest
58+
timeout-minutes: 30
59+
steps:
60+
- uses: actions/checkout@v4
61+
- uses: docker/setup-qemu-action@v3
62+
- uses: docker/setup-buildx-action@v3
63+
64+
- name: Build Image
65+
uses: docker/build-push-action@v6
66+
with:
67+
context: .
68+
push: false
69+
platforms: linux/amd64,linux/arm64,linux/ppc64le,linux/s390x
70+
cache-from: type=gha
71+
cache-to: type=gha,mode=max
72+
73+
# -------------
74+
# PUBLISH IMAGE
75+
# -------------
76+
publish:
77+
name: Publish Image
78+
needs: build-image
79+
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
80+
runs-on: ubuntu-latest
81+
timeout-minutes: 30
82+
env:
83+
IMAGE: ghcr.io/twogiants/console-functions-plugin
84+
steps:
85+
- uses: actions/checkout@v4
86+
- uses: docker/setup-qemu-action@v3
87+
- uses: docker/setup-buildx-action@v3
88+
89+
- name: Login to GHCR
90+
uses: docker/login-action@v3
91+
with:
92+
registry: ghcr.io
93+
username: ${{ github.actor }}
94+
password: ${{ secrets.GITHUB_TOKEN }}
95+
96+
- name: Build and Push Image
97+
id: build-and-push
98+
uses: docker/build-push-action@v6
99+
with:
100+
context: .
101+
push: true
102+
platforms: linux/amd64,linux/arm64,linux/ppc64le,linux/s390x
103+
tags: |
104+
${{ env.IMAGE }}:latest
105+
${{ env.IMAGE }}:sha-${{ github.sha }}
106+
cache-from: type=gha
107+
annotations: |
108+
index:org.opencontainers.image.description=Serverless Functions Console Plugin for OpenShift
109+
index:org.opencontainers.image.source=https://github.com/twoGiants/func-console
110+
index:org.opencontainers.image.vendor=https://github.com/twoGiants/func-console
111+
index:org.opencontainers.image.url=https://github.com/twoGiants/func-console/pkgs/container/console-functions-plugin
112+
113+
- name: Attest Build Provenance
114+
uses: actions/attest-build-provenance@v3
115+
with:
116+
subject-name: ${{ env.IMAGE }}
117+
subject-digest: ${{ steps.build-and-push.outputs.digest }}
118+
push-to-registry: true

README.md

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,35 @@ A Functions-as-a-Service PoC UI for the OpenShift Web Console. Developers create
44

55
Built as an [OpenShift Console dynamic plugin](https://github.com/openshift/console/tree/main/frontend/packages/console-dynamic-plugin-sdk) using React, TypeScript, and PatternFly 6.
66

7-
## Prerequisites
7+
## Deployment on cluster
8+
9+
### Prerequisites
10+
11+
- [oc](https://console.redhat.com/openshift/downloads) CLI
12+
- [Helm](https://helm.sh)
13+
- An [OpenShift 4.19 cluster](https://console.redhat.com/openshift/create)
14+
15+
### Installing the plugin
16+
17+
```shell
18+
oc new-project console-functions-plugin
19+
helm upgrade -i console-functions-plugin charts/openshift-console-plugin \
20+
-n console-functions-plugin --create-namespace \
21+
--set "plugin.image=ghcr.io/twogiants/console-functions-plugin:latest@sha256:<digest>"
22+
```
23+
24+
Available image tags are listed in the [container registry](https://github.com/twoGiants/func-console/pkgs/container/console-functions-plugin). Consult the chart [values](charts/openshift-console-plugin/values.yaml) file for additional parameters.
25+
26+
## Development
27+
28+
### Prerequisites
829

930
- [Node.js](https://nodejs.org/en/) (v18+)
1031
- [Yarn](https://yarnpkg.com) (v4)
1132
- [oc](https://console.redhat.com/openshift/downloads) CLI
1233
- [Docker](https://www.docker.com) or [podman 3.2.0+](https://podman.io)
1334
- An [OpenShift cluster](https://console.redhat.com/openshift/create)
1435

15-
## Development
16-
1736
### Option 1: Local
1837

1938
In one terminal window, run:
@@ -93,28 +112,6 @@ NOTE: If you have a Mac with Apple silicon, you will need to add the flag
93112
`--platform=linux/amd64` when building the image to target the correct platform
94113
to run in-cluster.
95114

96-
## Deployment on cluster
97-
98-
A [Helm](https://helm.sh) chart is available to deploy the plugin to an OpenShift environment.
99-
100-
The following Helm parameters are required:
101-
102-
`plugin.image`: The location of the image containing the plugin that was previously pushed
103-
104-
Additional parameters can be specified if desired. Consult the chart [values](charts/openshift-console-plugin/values.yaml) file for the full set of supported parameters.
105-
106-
### Installing the Helm Chart
107-
108-
Install the chart using the name of the plugin as the Helm release name into a new namespace or an existing namespace as specified by the `plugin.name` parameter and providing the location of the image within the `plugin.image` parameter by using the following command:
109-
110-
```shell
111-
helm upgrade -i my-plugin charts/openshift-console-plugin -n my-namespace --create-namespace --set plugin.image=my-plugin-image-location
112-
```
113-
114-
NOTE: When deploying on OpenShift 4.10, it is recommended to add the parameter `--set plugin.securityContext.enabled=false` which will omit configurations related to Pod Security.
115-
116-
NOTE: When defining i18n namespace, adhere `plugin__<name-of-the-plugin>` format. The name of the plugin should be extracted from the `consolePlugin` declaration within the [package.json](package.json) file.
117-
118115
## i18n
119116

120117
The plugin uses [react-i18next](https://react.i18next.com/) for translations. The i18n namespace must match

docs/WORKFLOW.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ For each comment: read the full text and its diff hunk context, make the fix, th
3131

3232
## Branching
3333

34-
Create a feature branch per plan: `<NNN>-<type>-<short-name>` where `<NNN>` matches the plan number and `<type>` the conventional commit type as per our [Git Commit Guide](references/commit-message-guide.md#conventional-commits). Example: `001-feat-function-list-empty-state`. If we're on a feature branch already do nothing.
34+
Create a feature branch per plan: `<NNN>-<type>-<short-name>` where `<NNN>` is determined by `./hack/next-plan-number.sh` (next PR number on the remote) and `<type>` is the conventional commit type as per our [Git Commit Guide](references/commit-message-guide.md#conventional-commits). The plan file uses the same number. Example: `010-feat-function-list-empty-state`. If we're on a feature branch already do nothing.
3535

3636
## Pull Requests
3737

docs/claude-progress.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,26 @@
11
# Claude Progress Log
22
# Newest entries first. Agents: append your entry at the top after the header.
33

4+
---
5+
## 2026-04-20 | Session: CI/CD pipeline and ESLint fixes
6+
Worked on: GitHub Actions CI/CD pipeline, ESLint config fixes, README restructure
7+
Completed:
8+
- Single CI workflow (ci.yml) with three jobs: checks (lint + test), build-image (multi-arch Docker build, no push), publish (build + push to GHCR, master only)
9+
- Multi-arch builds (amd64, arm64, ppc64le, s390x) via docker/setup-qemu-action + docker/setup-buildx-action, required for OCP
10+
- Build attestation signing via actions/attest-build-provenance, required for OCP
11+
- OCI annotations on image index (description, source, vendor, url), following knative/func patterns
12+
- Docker layer caching via GHA cache (build-image writes, publish reads)
13+
- Follows knative/func patterns: top-level permissions (id-token, contents, packages, attestations), concurrency groups, cancel-in-progress for PRs
14+
- Fixed ESLint config: removed redundant rule spreads in src/** block that re-enabled base no-unused-vars over @typescript-eslint/no-unused-vars (all 194 lint errors were config issues, not code issues)
15+
- Added Jest globals block for test files
16+
- Downgraded @console/pluginAPI shared dep to >=4.19.0
17+
- Restructured README: deployment section moved to top with OCP 4.19 prerequisite, GHCR registry link, separate prerequisites for deployment and development
18+
- Added hack/next-plan-number.sh for deterministic plan/branch numbering based on remote PR count
19+
- Updated WORKFLOW.md branching convention to use the helper script
20+
- 8 suites, 34 tests, all passing, zero lint errors
21+
Left off: PR #10 open. User needs to enable GITHUB_TOKEN write permissions in repo Settings and add branch protection rule for master.
22+
Blockers: None
23+
424
---
525
## 2026-04-17 | Session: FaaS route rename and nav restructure
626
Worked on: Rename routes from /functions to /faas, restructure nav for both perspectives

docs/features.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,5 +124,18 @@
124124
"Deployed functions without a matching repo still appear in the table with available cluster data (name, namespace, status, replicas, url)"
125125
],
126126
"passes": false
127+
},
128+
{
129+
"category": "technical",
130+
"description": "CI/CD: GitHub Actions pipelines for PR checks and master publish to GHCR, plus lint fixes and README deployment instructions",
131+
"steps": [
132+
"PR pipeline (.github/workflows/pr.yml): triggers on pull_request to master, runs yarn install --immutable, yarn lint, yarn test — branch cannot merge without passing checks and an approval",
133+
"Publish pipeline (.github/workflows/publish.yml): triggers on push to master (merged PRs), runs yarn install --immutable, yarn lint, yarn test, then builds multi-arch container image via docker/build-push-action using existing Dockerfile and pushes to ghcr.io/twogiants/console-functions-plugin with :latest and :sha-<commit> tags",
134+
"Both pipelines use actions/setup-node@v4 with node-version 22, corepack enable, and cache: yarn for Yarn install caching (GitHub runners ship Node 20 by default with corepack disabled)",
135+
"Both pipelines authenticate to GHCR using GITHUB_TOKEN secret with packages:write permission (token added to repo's Actions secrets)",
136+
"Add yarn lint script to package.json if missing, run it, and fix all lint errors in the codebase",
137+
"Update README.md deployment section (lines 96-117) — replace generic Helm boilerplate, placeholder commands, and obsolete OCP 4.10 / i18n notes with concrete instructions: oc new-project console-functions-plugin, helm upgrade -i console-functions-plugin charts/openshift-console-plugin -n console-functions-plugin --create-namespace --set plugin.image=ghcr.io/twogiants/console-functions-plugin:latest@sha256:<digest>"
138+
],
139+
"passes": true
127140
}
128141
]

0 commit comments

Comments
 (0)