Skip to content

Commit 33b1d9f

Browse files
committed
Add attestation
1 parent 373304a commit 33b1d9f

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

.github/workflows/release.yml

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,15 @@ on:
99
default: 'latest'
1010

1111
permissions:
12-
contents: read
13-
packages: write
12+
id-token: write
13+
contents: read
14+
attestations: write
15+
packages: write
16+
17+
env:
18+
REGISTRY: ghcr.io
19+
USER: githubsecuritylab
20+
IMAGE_NAME: seclab-taskflow-agent3
1421

1522
jobs:
1623
release:
@@ -25,6 +32,15 @@ jobs:
2532
python-version: '3.11'
2633

2734
- name: Create release
35+
id: docker_build
2836
run: |
29-
echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u GitHubSecurityLab --password-stdin
30-
python release_tools/publish_docker.py release.txt main.py ghcr.io/githubsecuritylab/seclab-taskflow-agent ${{ github.event.inputs.release_tag }}
37+
echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin
38+
DIGEST=$(python release_tools/publish_docker.py release.txt main.py ${{ env.REGISTRY }}/${{ env.USER }}/${{ env.IMAGE_NAME }} ${{ github.event.inputs.release_tag }} | grep '^Image digest: ' | cut -d':' -f2 | xargs)
39+
echo "digest=$DIGEST" >> $GITHUB_OUTPUT
40+
41+
- name: Generate artifact attestation
42+
uses: actions/attest-build-provenance@v3
43+
with:
44+
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
45+
subject-digest: '${{ steps.docker_build.outputs.digest }}'
46+
push-to-registry: true

release_tools/publish_docker.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,16 @@ def write_dockerfile(dest_dir, entrypoint):
8282
with open(os.path.join(dest_dir, "Dockerfile"), "w") as f:
8383
f.write(dockerfile)
8484

85+
def get_image_digest(image_name, tag):
86+
result = subprocess.run(
87+
["docker", "buildx", "imagetools", "inspect", f"{image_name}:{tag}"],
88+
stdout=subprocess.PIPE, check=True, text=True
89+
)
90+
for line in result.stdout.splitlines():
91+
if line.strip().startswith("Digest:"):
92+
return line.strip().split(":", 1)[1].strip()
93+
return None
94+
8595
def build_and_push_image(dest_dir, image_name, tag):
8696
# Build
8797
subprocess.run([
@@ -92,6 +102,8 @@ def build_and_push_image(dest_dir, image_name, tag):
92102
"docker", "push", f"{image_name}:{tag}"
93103
], check=True)
94104
print(f"Pushed {image_name}:{tag}")
105+
digest = get_image_digest(image_name, tag)
106+
print(f"Image digest: {digest}") # The prefix "Image digest: " is used for grepping in the release workflow
95107

96108
if __name__ == "__main__":
97109
if len(sys.argv) != 5:

0 commit comments

Comments
 (0)