Skip to content

Commit e8c2612

Browse files
committed
feat: added repo-copy code
1 parent 19ee8e1 commit e8c2612

File tree

4 files changed

+112
-0
lines changed

4 files changed

+112
-0
lines changed

.github/workflows/docker.yml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: Publish docker image
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
release_tag:
7+
description: 'Tag to release'
8+
required: true
9+
type: string
10+
11+
permissions:
12+
contents: read
13+
packages: write
14+
15+
jobs:
16+
build:
17+
runs-on: ubuntu-latest
18+
if: startsWith(github.event.inputs.release_tag, 'v')
19+
steps:
20+
- name: Harden the runner (Audit all outbound calls)
21+
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
22+
with:
23+
egress-policy: audit
24+
25+
- name: Checkout
26+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
27+
- name: Validate tag format
28+
run: |
29+
TAG=${{ github.event.inputs.release_tag }}
30+
if ! echo "$TAG" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+$'; then
31+
echo "❌ Invalid tag format: $TAG"
32+
exit 1
33+
fi
34+
echo "✅ Valid semver tag: $TAG"
35+
- name: Log in to GitHub Container Registry
36+
uses: step-security/docker-login-action@c3e677aae8393bc9c81cfdf9709648720ea4bd4d # v3.6.0
37+
with:
38+
registry: ghcr.io
39+
username: ${{ github.actor }}
40+
password: ${{ secrets.GITHUB_TOKEN }}
41+
42+
- name: Set up QEMU for ARM builds
43+
uses: step-security/setup-qemu-action@8c4aef027ab2df56e08f597afe6dd8cd31cb84f5 # v3.7.0
44+
45+
- name: Set up Docker Buildx
46+
uses: step-security/setup-buildx-action@c60a792b446ef83310733d5cd9d0c8d6870d043f # v3.12.0
47+
48+
- name: Build and push Docker image
49+
uses: step-security/docker-build-push-action@a8c3d08b23f8be6aeed43eb1a14ce6fe51284438 # v6.18.0
50+
with:
51+
context: ./repo-copy
52+
push: true
53+
platforms: linux/amd64,linux/arm64
54+
tags: |
55+
ghcr.io/${{ github.repository }}/repo-copy:${{ github.event.inputs.release_tag }}

repo-copy/Dockerfile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
FROM golang:1.17-alpine as base
2+
RUN go install github.com/google/go-containerregistry/cmd/crane@v0.6.0
3+
4+
FROM golang:1.17-alpine as repo-copy
5+
WORKDIR /go/src/github.com/akhilerm/repo-copy
6+
RUN --mount=target=. go build -o /out/repo-copy ./
7+
8+
FROM alpine
9+
COPY --from=base /go/bin/crane /bin/crane
10+
COPY --from=repo-copy /out/repo-copy /bin/repo-copy
11+
ENTRYPOINT ["/bin/repo-copy"]

repo-copy/go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module github.com/step-security/repo-copy
2+
3+
go 1.17

repo-copy/main.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package main
2+
3+
import (
4+
"flag"
5+
"fmt"
6+
"os"
7+
"os/exec"
8+
)
9+
10+
func executeCommand(args []string) error {
11+
fmt.Println("executing crane with args:", args)
12+
cmd := exec.Command("crane", args...)
13+
cmd.Stdout = os.Stdout
14+
cmd.Stderr = os.Stderr
15+
return cmd.Run()
16+
}
17+
18+
func replicateImage(src string, dest string) error {
19+
return executeCommand([]string{"copy", src, dest})
20+
}
21+
22+
func replicateToAll(src string, dest []string) error {
23+
for _, d := range dest {
24+
if err := replicateImage(src, d); err != nil {
25+
return err
26+
}
27+
}
28+
return nil
29+
}
30+
31+
func main() {
32+
flag.Parse()
33+
args := flag.Args()
34+
35+
if len(args) < 2 {
36+
fmt.Fprintf(os.Stderr, "usage: %s <src> <dest> [<dest>]\n", os.Args[0])
37+
os.Exit(1)
38+
}
39+
40+
if err := replicateToAll(args[0], args[1:]); err != nil {
41+
panic(err)
42+
}
43+
}

0 commit comments

Comments
 (0)