Skip to content

Commit 0cb33c1

Browse files
authored
Initial commit
0 parents  commit 0cb33c1

13 files changed

Lines changed: 863 additions & 0 deletions

File tree

.github/ci.yaml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
version: 1
2+
ghcr:
3+
upload: true
4+
cve-scan: true
5+
6+
registries:
7+
## Example of specifying registries
8+
# docker.io:
9+
# uri: docker.io/ubuntu
10+
# auth:
11+
# - method: basic
12+
# config:
13+
# username: secrets.DOCKERHUB_USERNAME # @@@@@@ DO NOT PUT ACTUAL CREDENTIALS HERE @@@@@@
14+
# password: secrets.DOCKERHUB_TOKEN # @@@@@@ DO NOT PUT ACTUAL CREDENTIALS HERE @@@@@@
15+
# rocksdev-ecr-public:
16+
# uri: public.ecr.aws/rocksdev
17+
# auth:
18+
# - method: ecr-public
19+
# config:
20+
# region: us-east-1
21+
# username: secrets.AWS_ACCESS_KEY_ID # @@@@@@ DO NOT PUT ACTUAL CREDENTIALS HERE @@@@@@
22+
# password: secrets.AWS_SECRET_ACCESS_KEY # @@@@@@ DO NOT PUT ACTUAL CREDENTIALS HERE @@@@@@
23+
24+
images:
25+
- directory: "*"
26+
27+
## Example of specifying different registries for a specific rock
28+
# - directory: "my-rock-name/0.1-24.04"
29+
# registries:
30+
# - docker.io
31+
# - rocksdev-ecr-public
32+
33+
## Example of specifying pro-services with custom config
34+
# - directory: "my-rock-name/0.1-24.04"
35+
# pro:
36+
# services:
37+
# - esm-apps
38+
# - esm-infra
39+
# config:
40+
# token: secrets.MY_PRO_TOKEN # @@@@@@ DO NOT PUT ACTUAL CREDENTIALS HERE @@@@@@
41+
# artifact-passphrase: secrets.MY_PASSPHRASE # @@@@@@ DO NOT PUT ACTUAL CREDENTIALS HERE @@@@@@
42+
# registries:
43+
# ...

.github/workflows/cve-scan.yaml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Scan CVEs dispatch
2+
3+
on:
4+
workflow_dispatch:
5+
schedule:
6+
- cron: "0 1 * * *"
7+
8+
jobs:
9+
10+
read-config:
11+
runs-on: ubuntu-latest
12+
outputs:
13+
ghcr-scanning: ${{ steps.read-ci-config.outputs.ghcr-cve-scan }}
14+
build-matrix: ${{ steps.read-ci-config.outputs.build-matrix }}
15+
steps:
16+
- name: Checkout repository
17+
uses: actions/checkout@v5
18+
19+
- name: Read .github/ci.yaml
20+
id: read-ci-config
21+
uses: canonical/rocks-template-actions/actions/read-ci-config@v1
22+
23+
run-scan:
24+
name: Run scan for released images
25+
needs: [read-config]
26+
uses: canonical/oci-factory/.github/workflows/Vulnerability-Scan.yaml@main
27+
strategy:
28+
matrix: ${{ fromJson(needs.read-config.outputs.build-matrix) }}
29+
with:
30+
oci-image-name: ghcr.io/${{ github.repository }}/${{ matrix.name }}:${{ matrix.tag }}
31+
create-issue: true
32+
trivyignore-path: ${{ matrix.directory }}/.trivyignore
33+
permissions:
34+
contents: read
35+
packages: read
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# This workflow is intended for internal Canonical repositories only.
2+
# It includes steps that rely on internal actions or secrets,
3+
# and it performs additional checks to prevent accidental usage in public repositories.
4+
# If you are working in a public repository, please use the .github/workflows/image.yaml workflow instead.
5+
#
6+
name: Build and Publish Rocks (Internal)
7+
8+
on:
9+
# Uncomment these lines to enable the workflow on push and pull_request events
10+
# push:
11+
# branches: [main]
12+
# pull_request:
13+
# branches: [main]
14+
workflow_dispatch:
15+
16+
jobs:
17+
18+
prepare:
19+
runs-on: ubuntu-latest
20+
outputs:
21+
ghcr-upload: ${{ steps.read-ci-config.outputs.ghcr-upload }}
22+
build-matrix: ${{ steps.read-ci-config.outputs.build-matrix }}
23+
upload-matrix: ${{ steps.read-ci-config.outputs.upload-matrix }}
24+
steps:
25+
- name: Pre-Check
26+
if: |
27+
github.repository_owner != 'canonical' ||
28+
github.event.repository.visibility == 'public'
29+
run: |
30+
echo "::error::This workflow is intended for internal repositories only. Please use the .github/workflows/image.yaml workflow instead."
31+
exit 1
32+
33+
- name: Checkout Repository
34+
uses: actions/checkout@v5
35+
36+
- name: Read .github/ci.yaml
37+
id: read-ci-config
38+
uses: canonical/rocks-template-actions/actions/read-ci-config@v1
39+
40+
41+
build-internal:
42+
needs: [prepare]
43+
strategy:
44+
fail-fast: true
45+
matrix: ${{ fromJSON(needs.prepare.outputs.build-matrix) }}
46+
uses: canonical/oci-factory-internal/.github/workflows/Build-Rock.yaml@main
47+
with:
48+
rock-repo: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
49+
rock-repo-commit: ${{ github.ref }}
50+
rockfile-directory: ${{ matrix.directory }}
51+
oci-archive-name: ${{ matrix.artifact-name }}
52+
secrets:
53+
host-github-token: ${{ secrets.GITHUB_TOKEN }}
54+
source-github-token: ${{ secrets.REPO_CLONER_TOKEN }}
55+
56+
57+
test:
58+
needs: [prepare, build-internal]
59+
strategy:
60+
fail-fast: false
61+
matrix: ${{ fromJson(needs.prepare.outputs.build-matrix) }}
62+
uses: canonical/oci-factory/.github/workflows/Test-Rock.yaml@main
63+
with:
64+
oci-archive-name: ${{ matrix.artifact-name }}
65+
66+
67+
upload-ghcr:
68+
needs: [prepare, test]
69+
runs-on: ubuntu-latest
70+
if: |
71+
needs.prepare.outputs.ghcr-upload == 'true' &&
72+
github.event_name != 'pull_request' &&
73+
github.ref == 'refs/heads/main'
74+
strategy:
75+
matrix: ${{ fromJSON(needs.prepare.outputs.build-matrix) }}
76+
fail-fast: false
77+
permissions:
78+
packages: write
79+
steps:
80+
- name: Upload Rock to GHCR
81+
uses: canonical/oci-factory/.github/actions/upload-rock@main
82+
with:
83+
artifact_name: ${{ matrix.artifact-name }}
84+
tags: ${{ matrix.tag }}
85+
name: ${{ matrix.name }}
86+
registry: ghcr.io/${{ github.repository }}
87+
username: ${{ github.actor }}
88+
password: ${{ secrets.GITHUB_TOKEN }}
89+
90+
91+
upload-registries:
92+
needs: [prepare, test]
93+
runs-on: ubuntu-latest
94+
if: |
95+
needs.prepare.outputs.upload-matrix != '{"include": []}' &&
96+
github.event_name != 'pull_request' &&
97+
github.ref == 'refs/heads/main'
98+
strategy:
99+
matrix: ${{ fromJSON(needs.prepare.outputs.upload-matrix) }}
100+
fail-fast: false
101+
steps:
102+
- name: Prepare ECR Session Token
103+
if: ${{ contains(matrix.registry-auth-method, 'ecr') }}
104+
id: get-ecr-token
105+
env:
106+
AWS_ACCESS_KEY_ID: ${{ secrets[matrix.registry-auth-username] }}
107+
AWS_SECRET_ACCESS_KEY: ${{ secrets[matrix.registry-auth-password] }}
108+
run: |
109+
session_token=$(aws ${{ matrix.registry-auth-method }} \
110+
get-login-password \
111+
--region ${{ matrix.registry-auth-region }} \
112+
)
113+
echo "::add-mask::$session_token"
114+
echo "aws-session-token=$session_token" >> $GITHUB_OUTPUT
115+
116+
- name: Upload Rock to ECR
117+
uses: canonical/oci-factory/.github/actions/upload-rock@main
118+
if: ${{ contains(matrix.registry-auth-method, 'ecr') }}
119+
with:
120+
artifact_name: ${{ matrix.artifact-name }}
121+
tags: ${{ matrix.tag }}
122+
name: ${{ matrix.name }}
123+
registry: ${{ matrix.registry-uri }}
124+
username: AWS
125+
password: ${{ steps.get-ecr-token.outputs.aws-session-token }}
126+
127+
- name: Upload Rock to Registry
128+
uses: canonical/oci-factory/.github/actions/upload-rock@main
129+
if: matrix.registry-auth-method == 'basic'
130+
with:
131+
artifact_name: ${{ matrix.artifact-name }}
132+
tags: ${{ matrix.tag }}
133+
name: ${{ matrix.name }}
134+
registry: ${{ matrix.registry-uri }}
135+
username: ${{ secrets[matrix.registry-auth-username] }}
136+
password: ${{ secrets[matrix.registry-auth-password] }}
137+

.github/workflows/image.yaml

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
name: Build and Publish Rocks
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
workflow_dispatch:
9+
10+
jobs:
11+
prepare:
12+
runs-on: ubuntu-latest
13+
outputs:
14+
ghcr-upload: ${{ steps.read-ci-config.outputs.ghcr-upload }}
15+
build-matrix: ${{ steps.read-ci-config.outputs.build-matrix }}
16+
upload-matrix: ${{ steps.read-ci-config.outputs.upload-matrix }}
17+
arch-map: ${{ steps.set-map.outputs.arch-map }}
18+
steps:
19+
- name: Checkout Repository
20+
uses: actions/checkout@v5
21+
22+
- name: Read .github/ci.yaml
23+
id: read-ci-config
24+
uses: canonical/rocks-template-actions/actions/read-ci-config@v1
25+
26+
- name: Set Architecture Map
27+
id: set-map
28+
run: |
29+
if [[ "${{ github.repository_owner }}" != "canonical" ]]; then
30+
echo 'arch-map={"amd64":["ubuntu-24.04"],"arm64":["ubuntu-24.04-arm"]}' >> $GITHUB_OUTPUT
31+
fi
32+
33+
# TODO: remove once the pro-feature is stable in rockcraft
34+
# Warn the user if using tests in a pro enabled build
35+
- name: Check Pro and Test Incompatibility
36+
run: |
37+
build_matrix='${{ steps.read-ci-config.outputs.build-matrix }}'
38+
39+
# Use jq to iterate over the 'include' array
40+
echo "$build_matrix" | jq -c '.include[]' | while read -r row; do
41+
directory=$(echo "$row" | jq -r '.["directory"] // "unknown"')
42+
pro_services=$(echo "$row" | jq -r '.["pro-services"] // ""')
43+
run_tests=$(echo "$row" | jq -r '.["run-tests"] // "false"')
44+
45+
if [[ -n "$pro_services" && "$run_tests" == "true" ]]; then
46+
echo "::warning::Tests for Pro Services are currently not supported. Rockcraft tests will be skipped for ${directory}."
47+
fi
48+
done
49+
50+
51+
build:
52+
needs: [prepare]
53+
strategy:
54+
matrix: ${{ fromJSON(needs.prepare.outputs.build-matrix) }}
55+
uses: canonical/oci-factory/.github/workflows/Build-Rock.yaml@main
56+
with:
57+
rock-repo: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
58+
rock-repo-commit: ${{ github.head_ref || github.ref_name }}
59+
rockfile-directory: ${{ matrix.directory }}
60+
oci-archive-name: ${{ matrix.artifact-name }}
61+
arch-map: ${{ needs.prepare.outputs.arch-map }}
62+
rockcraft-test: ${{ matrix.run-tests }}
63+
pro-services: ${{ matrix.pro-services }}
64+
secrets:
65+
source-github-token: ${{ secrets.REPO_CLONER_TOKEN }}
66+
pro-token: ${{ secrets[matrix.pro-token] }}
67+
pro-artifact-passphrase: ${{ secrets[matrix.pro-artifact-passphrase] }}
68+
69+
70+
test:
71+
needs: [prepare, build]
72+
strategy:
73+
fail-fast: false
74+
matrix: ${{ fromJSON(needs.prepare.outputs.build-matrix) }}
75+
uses: canonical/oci-factory/.github/workflows/Test-Rock.yaml@main
76+
with:
77+
oci-archive-name: ${{ matrix.artifact-name }}
78+
secrets:
79+
pro-artifact-passphrase: ${{ secrets[matrix.pro-artifact-passphrase] }}
80+
81+
82+
upload-ghcr:
83+
needs: [prepare, test]
84+
runs-on: ubuntu-latest
85+
if: |
86+
needs.prepare.outputs.ghcr-upload == 'true' &&
87+
github.event_name != 'pull_request' &&
88+
github.ref == 'refs/heads/main'
89+
strategy:
90+
matrix: ${{ fromJSON(needs.prepare.outputs.build-matrix) }}
91+
fail-fast: false
92+
permissions:
93+
packages: write
94+
steps:
95+
- name: Pre-Check Pro Enabled Rocks
96+
if: ${{ github.event.repository.visibility == 'public' && matrix.pro-services != '' }}
97+
run: |
98+
echo "::warning::Uploading Pro enabled rocks to GHCR is not allowed for public repositories."
99+
100+
- name: Upload Rock to GHCR
101+
if: ${{ github.event.repository.visibility != 'public' || matrix.pro-services == '' }}
102+
uses: canonical/oci-factory/.github/actions/upload-rock@main
103+
with:
104+
artifact_name: ${{ matrix.artifact-name }}
105+
tags: ${{ matrix.tag }}
106+
name: ${{ matrix.name }}
107+
registry: ghcr.io/${{ github.repository }}
108+
username: ${{ github.actor }}
109+
password: ${{ secrets.GITHUB_TOKEN }}
110+
decrypt-passphrase: ${{ secrets[matrix.pro-artifact-passphrase] }}
111+
112+
113+
upload-registries:
114+
needs: [prepare, test]
115+
runs-on: ubuntu-latest
116+
if: |
117+
needs.prepare.outputs.upload-matrix != '{"include": []}' &&
118+
github.event_name != 'pull_request' &&
119+
github.ref == 'refs/heads/main'
120+
strategy:
121+
matrix: ${{ fromJSON(needs.prepare.outputs.upload-matrix) }}
122+
fail-fast: false
123+
steps:
124+
- name: Prepare ECR Session Token
125+
if: ${{ contains(matrix.registry-auth-method, 'ecr') }}
126+
id: get-ecr-token
127+
env:
128+
AWS_ACCESS_KEY_ID: ${{ secrets[matrix.registry-auth-username] }}
129+
AWS_SECRET_ACCESS_KEY: ${{ secrets[matrix.registry-auth-password] }}
130+
run: |
131+
session_token=$(aws ${{ matrix.registry-auth-method }} \
132+
get-login-password \
133+
--region ${{ matrix.registry-auth-region }} \
134+
)
135+
echo "::add-mask::$session_token"
136+
echo "aws-session-token=$session_token" >> $GITHUB_OUTPUT
137+
138+
- name: Upload Rock to ECR
139+
uses: canonical/oci-factory/.github/actions/upload-rock@main
140+
if: ${{ contains(matrix.registry-auth-method, 'ecr') }}
141+
with:
142+
artifact_name: ${{ matrix.artifact-name }}
143+
tags: ${{ matrix.tag }}
144+
name: ${{ matrix.name }}
145+
registry: ${{ matrix.registry-uri }}
146+
username: AWS
147+
password: ${{ steps.get-ecr-token.outputs.aws-session-token }}
148+
decrypt-passphrase: ${{ secrets[matrix.pro-artifact-passphrase] }}
149+
150+
- name: Upload Rock to Registry
151+
uses: canonical/oci-factory/.github/actions/upload-rock@main
152+
if: matrix.registry-auth-method == 'basic'
153+
with:
154+
artifact_name: ${{ matrix.artifact-name }}
155+
tags: ${{ matrix.tag }}
156+
name: ${{ matrix.name }}
157+
registry: ${{ matrix.registry-uri }}
158+
username: ${{ secrets[matrix.registry-auth-username] }}
159+
password: ${{ secrets[matrix.registry-auth-password] }}
160+
decrypt-passphrase: ${{ secrets[matrix.pro-artifact-passphrase] }}

.gitignore

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# rock
2+
*.rock
3+
4+
# OS Files
5+
.DS_store
6+
7+
# Spread
8+
.craft-spread*/
9+
.spread-reuse*
10+
11+
# IDE
12+
.vs_code/
13+
.vscode/
14+
.idea/
15+

0 commit comments

Comments
 (0)