Build Container Image with OCI Labels #2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build Container Image with OCI Labels | |
| on: | |
| # Trigger on merge to main | |
| push: | |
| branches: | |
| - main | |
| # Manual trigger | |
| workflow_dispatch: | |
| inputs: | |
| custom_tag: | |
| description: 'Custom tag for the image (optional)' | |
| required: false | |
| default: 'manual-build' | |
| env: | |
| # Container Image Labeling | |
| TEAM_ORGDATA_EMAIL: "[email protected]" | |
| TEAM_ORGDATA_ID: "ept" | |
| # Default values - customize these for your project | |
| DEFAULT_IMAGE_TITLE: "My Example Application" | |
| IMAGE_VENDOR: "ACME Corporation" | |
| IMAGE_LICENSES: "Apache-2.0" | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # Full history for version detection | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Extract base image info | |
| id: base_image | |
| run: | | |
| # Extract base image from Dockerfile | |
| cd test-app | |
| BASE_IMAGE=$(grep -E '^FROM' Dockerfile | head -n 1 | awk '{print $2}') | |
| # Handle ARG-based FROM (e.g., FROM ${BASE_IMAGE}) | |
| if [[ "$BASE_IMAGE" == \$* ]]; then | |
| ARG_NAME=$(echo "$BASE_IMAGE" | tr -d '${}') | |
| BASE_IMAGE=$(grep -E "^ARG\s+$ARG_NAME=" Dockerfile | cut -d'=' -f2) | |
| fi | |
| echo "Base image found: $BASE_IMAGE" | |
| # Check for scratch image | |
| if [[ "$BASE_IMAGE" == "scratch" ]]; then | |
| echo "name=scratch" >> $GITHUB_OUTPUT | |
| echo "digest=N/A (scratch image)" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| echo "name=$BASE_IMAGE" >> $GITHUB_OUTPUT | |
| # Pull base image and get digest | |
| docker pull "$BASE_IMAGE" | |
| BASE_DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' "$BASE_IMAGE" 2>/dev/null | cut -d'@' -f2 || echo "N/A") | |
| echo "digest=$BASE_DIGEST" >> $GITHUB_OUTPUT | |
| echo "Base image digest: $BASE_DIGEST" | |
| - name: Get SPDX license id | |
| id: license | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| spdx=$( | |
| curl -sS \ | |
| -H "Authorization: Bearer $GH_TOKEN" \ | |
| -H "Accept: application/vnd.github+json" \ | |
| "${{ github.api_url }}/repos/${{ github.repository }}/license" \ | |
| | jq -r '.license.spdx_id // empty' | |
| ) | |
| if [ -z "$spdx" ] || [ "$spdx" = "NOASSERTION" ]; then | |
| echo "Could not determine SPDX id (missing license or unrecognized)." | |
| exit 1 | |
| fi | |
| echo "spdx=$spdx" >> "$GITHUB_OUTPUT" | |
| echo "SPDX: $spdx" | |
| - name: Generate Docker metadata | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: test-app | |
| tags: | | |
| type=ref,event=branch | |
| type=sha,prefix= | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| # Labels using OCI standard keys | |
| labels: | | |
| org.opencontainers.image.authors=${{ env.TEAM_ORGDATA_EMAIL }} | |
| com.vonage.orgdata.id=${{ env.TEAM_ORGDATA_ID }} | |
| org.opencontainers.image.title=${{ github.event.repository }} | |
| org.opencontainers.image.base.name=${{ steps.base_image.outputs.name }} | |
| org.opencontainers.image.base.digest=${{ steps.base_image.outputs.digest }} | |
| org.opencontainers.image.description=${{ github.event.repository.description }} | |
| org.opencontainers.image.url=${{ github.repositoryUrl }}/test-app/Dockerfile | |
| org.opencontainers.image.documentation=${{ github.repositoryUrl }}/README.md | |
| org.opencontainers.image.vendor=${{ github.repository_owner }} | |
| org.opencontainers.image.licenses=${{ steps.license.outputs.spdx }} | |
| - name: Build the app | |
| run: | | |
| cd test-app | |
| make build | |
| - name: Build image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: test-app | |
| push: false | |
| load: true # Load image into local Docker daemon | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Display image labels | |
| run: | | |
| IMAGE=$(echo "${{ steps.meta.outputs.tags }}" | head -1) | |
| echo "Image: $IMAGE" | |
| echo "" | |
| docker inspect "$IMAGE" --format='{{json .Config.Labels}}' | jq '.' |