Merge pull request #746 from crazy-max/attests-sbom-provenance-inputs
add attests, provenance and sbom inputs
This commit is contained in:
		
						commit
						c40bf0fdf6
					
				
							
								
								
									
										148
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										148
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							@ -84,7 +84,7 @@ jobs:
 | 
			
		||||
      -
 | 
			
		||||
        name: Inspect
 | 
			
		||||
        run: |
 | 
			
		||||
          docker buildx imagetools inspect localhost:5000/name/app:1.0.0
 | 
			
		||||
          docker buildx imagetools inspect localhost:5000/name/app:1.0.0 --format '{{json .}}'
 | 
			
		||||
      -
 | 
			
		||||
        name: Check digest
 | 
			
		||||
        run: |
 | 
			
		||||
@ -143,7 +143,7 @@ jobs:
 | 
			
		||||
      -
 | 
			
		||||
        name: Inspect
 | 
			
		||||
        run: |
 | 
			
		||||
          docker buildx imagetools inspect localhost:5000/name/app:1.0.0
 | 
			
		||||
          docker buildx imagetools inspect localhost:5000/name/app:1.0.0 --format '{{json .}}'
 | 
			
		||||
      -
 | 
			
		||||
        name: Check digest
 | 
			
		||||
        run: |
 | 
			
		||||
@ -190,7 +190,7 @@ jobs:
 | 
			
		||||
      -
 | 
			
		||||
        name: Inspect
 | 
			
		||||
        run: |
 | 
			
		||||
          docker buildx imagetools inspect localhost:5000/name/app:1.0.0
 | 
			
		||||
          docker buildx imagetools inspect localhost:5000/name/app:1.0.0 --format '{{json .}}'
 | 
			
		||||
      -
 | 
			
		||||
        name: Check digest
 | 
			
		||||
        run: |
 | 
			
		||||
@ -491,6 +491,97 @@ jobs:
 | 
			
		||||
          cache-from: type=gha,scope=nocachefilter
 | 
			
		||||
          cache-to: type=gha,scope=nocachefilter,mode=max
 | 
			
		||||
 | 
			
		||||
  attests-compat:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    strategy:
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
      matrix:
 | 
			
		||||
        include:
 | 
			
		||||
          - buildx: latest
 | 
			
		||||
            buildkit: moby/buildkit:buildx-stable-1
 | 
			
		||||
          - buildx: latest
 | 
			
		||||
            buildkit: moby/buildkit:v0.10.6
 | 
			
		||||
          - buildx: v0.9.1
 | 
			
		||||
            buildkit: moby/buildkit:buildx-stable-1
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: Checkout
 | 
			
		||||
        uses: actions/checkout@v3
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up Docker Buildx
 | 
			
		||||
        uses: docker/setup-buildx-action@v2
 | 
			
		||||
        with:
 | 
			
		||||
          version: ${{ matrix.buildx }}
 | 
			
		||||
          driver-opts: |
 | 
			
		||||
            network=host
 | 
			
		||||
            image=${{ matrix.buildkit }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Build
 | 
			
		||||
        uses: ./
 | 
			
		||||
        with:
 | 
			
		||||
          context: ./test/go
 | 
			
		||||
          file: ./test/go/Dockerfile
 | 
			
		||||
          outputs: type=cacheonly
 | 
			
		||||
 | 
			
		||||
  sbom:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    strategy:
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
      matrix:
 | 
			
		||||
        include:
 | 
			
		||||
          - target: image
 | 
			
		||||
            output: type=image,name=localhost:5000/name/app:latest,push=true
 | 
			
		||||
          - target: binary
 | 
			
		||||
            output: /tmp/buildx-build
 | 
			
		||||
    services:
 | 
			
		||||
      registry:
 | 
			
		||||
        image: registry:2
 | 
			
		||||
        ports:
 | 
			
		||||
          - 5000:5000
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: Checkout
 | 
			
		||||
        uses: actions/checkout@v3
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up Docker Buildx
 | 
			
		||||
        uses: docker/setup-buildx-action@v2
 | 
			
		||||
        with:
 | 
			
		||||
          version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
 | 
			
		||||
          driver-opts: |
 | 
			
		||||
            network=host
 | 
			
		||||
            image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Build
 | 
			
		||||
        uses: ./
 | 
			
		||||
        with:
 | 
			
		||||
          context: ./test/go
 | 
			
		||||
          file: ./test/go/Dockerfile
 | 
			
		||||
          target: ${{ matrix.target }}
 | 
			
		||||
          outputs: ${{ matrix.output }}
 | 
			
		||||
          sbom: true
 | 
			
		||||
          cache-from: type=gha,scope=attests-${{ matrix.target }}
 | 
			
		||||
          cache-to: type=gha,scope=attests-${{ matrix.target }},mode=max
 | 
			
		||||
      -
 | 
			
		||||
        name: Inspect image
 | 
			
		||||
        if: matrix.target == 'image'
 | 
			
		||||
        run: |
 | 
			
		||||
          docker buildx imagetools inspect localhost:5000/name/app:latest --format '{{json .}}'
 | 
			
		||||
      -
 | 
			
		||||
        name: Check output folder
 | 
			
		||||
        if: matrix.target == 'binary'
 | 
			
		||||
        run: |
 | 
			
		||||
          tree /tmp/buildx-build
 | 
			
		||||
      -
 | 
			
		||||
        name: Print provenance
 | 
			
		||||
        if: matrix.target == 'binary'
 | 
			
		||||
        run: |
 | 
			
		||||
          cat /tmp/buildx-build/provenance.json | jq
 | 
			
		||||
      -
 | 
			
		||||
        name: Print SBOM
 | 
			
		||||
        if: matrix.target == 'binary'
 | 
			
		||||
        run: |
 | 
			
		||||
          cat /tmp/buildx-build/sbom.spdx.json | jq
 | 
			
		||||
 | 
			
		||||
  multi:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    strategy:
 | 
			
		||||
@ -536,7 +627,7 @@ jobs:
 | 
			
		||||
      -
 | 
			
		||||
        name: Inspect
 | 
			
		||||
        run: |
 | 
			
		||||
          docker buildx imagetools inspect localhost:5000/name/app:1.0.0
 | 
			
		||||
          docker buildx imagetools inspect localhost:5000/name/app:1.0.0 --format '{{json .}}'
 | 
			
		||||
      -
 | 
			
		||||
        name: Check digest
 | 
			
		||||
        run: |
 | 
			
		||||
@ -649,7 +740,6 @@ jobs:
 | 
			
		||||
        uses: docker/setup-qemu-action@v2
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up Docker Buildx
 | 
			
		||||
        id: buildx
 | 
			
		||||
        uses: docker/setup-buildx-action@v2
 | 
			
		||||
        with:
 | 
			
		||||
          version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
 | 
			
		||||
@ -657,7 +747,7 @@ jobs:
 | 
			
		||||
            network=host
 | 
			
		||||
            image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
 | 
			
		||||
      -
 | 
			
		||||
        name: Build and push (1)
 | 
			
		||||
        name: Build and push
 | 
			
		||||
        id: docker_build
 | 
			
		||||
        uses: ./
 | 
			
		||||
        with:
 | 
			
		||||
@ -672,54 +762,16 @@ jobs:
 | 
			
		||||
          cache-from: type=registry,ref=localhost:5000/name/app
 | 
			
		||||
          cache-to: type=inline
 | 
			
		||||
      -
 | 
			
		||||
        name: Inspect (1)
 | 
			
		||||
        name: Inspect
 | 
			
		||||
        run: |
 | 
			
		||||
          docker buildx imagetools inspect localhost:5000/name/app:latest
 | 
			
		||||
          docker buildx imagetools inspect localhost:5000/name/app:latest --format '{{json .}}'
 | 
			
		||||
      -
 | 
			
		||||
        name: Check digest (1)
 | 
			
		||||
        name: Check digest
 | 
			
		||||
        run: |
 | 
			
		||||
          if [ -z "${{ steps.docker_build.outputs.digest }}" ]; then
 | 
			
		||||
            echo "::error::Digest should not be empty"
 | 
			
		||||
            exit 1
 | 
			
		||||
          fi
 | 
			
		||||
      -
 | 
			
		||||
        name: Prune
 | 
			
		||||
        run: |
 | 
			
		||||
          docker buildx prune -a -f --verbose
 | 
			
		||||
      -
 | 
			
		||||
        name: Build and push (2)
 | 
			
		||||
        id: docker_build2
 | 
			
		||||
        uses: ./
 | 
			
		||||
        with:
 | 
			
		||||
          context: ./test
 | 
			
		||||
          file: ./test/multi.Dockerfile
 | 
			
		||||
          builder: ${{ steps.buildx.outputs.name }}
 | 
			
		||||
          platforms: linux/amd64,linux/arm64
 | 
			
		||||
          push: true
 | 
			
		||||
          tags: |
 | 
			
		||||
            localhost:5000/name/app:latest
 | 
			
		||||
            localhost:5000/name/app:1.0.0
 | 
			
		||||
          cache-from: type=registry,ref=localhost:5000/name/app
 | 
			
		||||
          cache-to: type=inline
 | 
			
		||||
      -
 | 
			
		||||
        name: Inspect (2)
 | 
			
		||||
        run: |
 | 
			
		||||
          docker buildx imagetools inspect localhost:5000/name/app:latest
 | 
			
		||||
      -
 | 
			
		||||
        name: Check digest (2)
 | 
			
		||||
        run: |
 | 
			
		||||
          if [ -z "${{ steps.docker_build2.outputs.digest }}" ]; then
 | 
			
		||||
            echo "::error::Digest should not be empty"
 | 
			
		||||
            exit 1
 | 
			
		||||
          fi
 | 
			
		||||
      -
 | 
			
		||||
        name: Compare digests
 | 
			
		||||
        run: |
 | 
			
		||||
          echo Compare "${{ steps.docker_build.outputs.digest }}" with "${{ steps.docker_build2.outputs.digest }}"
 | 
			
		||||
          if [ "${{ steps.docker_build.outputs.digest }}" != "${{ steps.docker_build2.outputs.digest }}" ]; then
 | 
			
		||||
            echo "::error::Digests should be identical"
 | 
			
		||||
            exit 1
 | 
			
		||||
          fi
 | 
			
		||||
 | 
			
		||||
  github-cache:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
@ -760,7 +812,7 @@ jobs:
 | 
			
		||||
      -
 | 
			
		||||
        name: Inspect
 | 
			
		||||
        run: |
 | 
			
		||||
          docker buildx imagetools inspect localhost:5000/name/app:1.0.0
 | 
			
		||||
          docker buildx imagetools inspect localhost:5000/name/app:1.0.0 --format '{{json .}}'
 | 
			
		||||
 | 
			
		||||
  standalone:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/workflows/e2e.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/e2e.yml
									
									
									
									
										vendored
									
									
								
							@ -120,4 +120,4 @@ jobs:
 | 
			
		||||
        name: Check manifest
 | 
			
		||||
        if: github.event_name != 'pull_request'
 | 
			
		||||
        run: |
 | 
			
		||||
          docker buildx imagetools inspect ${{ matrix.slug }}:${{ steps.meta.outputs.version }}
 | 
			
		||||
          docker buildx imagetools inspect ${{ matrix.slug }}:${{ steps.meta.outputs.version }} --format '{{json .}}'
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/workflows/example.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/example.yml
									
									
									
									
										vendored
									
									
								
							@ -71,4 +71,4 @@ jobs:
 | 
			
		||||
        name: Check manifest
 | 
			
		||||
        if: github.event_name != 'pull_request'
 | 
			
		||||
        run: |
 | 
			
		||||
          docker buildx imagetools inspect ${{ env.DOCKER_IMAGE }}:${{ steps.meta.outputs.version }}
 | 
			
		||||
          docker buildx imagetools inspect ${{ env.DOCKER_IMAGE }}:${{ steps.meta.outputs.version }} --format '{{json .}}'
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										61
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										61
									
								
								README.md
									
									
									
									
									
								
							@ -190,35 +190,38 @@ Following inputs can be used as `step.with` keys
 | 
			
		||||
> tags: name/app:latest,name/app:1.0.0
 | 
			
		||||
> ```
 | 
			
		||||
 | 
			
		||||
| Name               | Type     | Description                                                                                                                                                                       |
 | 
			
		||||
|--------------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
 | 
			
		||||
| `add-hosts`        | List/CSV | List of [customs host-to-IP mapping](https://docs.docker.com/engine/reference/commandline/build/#add-entries-to-container-hosts-file---add-host) (e.g., `docker:10.180.0.1`)      |
 | 
			
		||||
| `allow`            | List/CSV | List of [extra privileged entitlement](https://docs.docker.com/engine/reference/commandline/buildx_build/#allow) (e.g., `network.host,security.insecure`)                         |
 | 
			
		||||
| `builder`          | String   | Builder instance (see [setup-buildx](https://github.com/docker/setup-buildx-action) action)                                                                                       |
 | 
			
		||||
| `build-args`       | List     | List of [build-time variables](https://docs.docker.com/engine/reference/commandline/buildx_build/#build-arg)                                                                      |
 | 
			
		||||
| `build-contexts`   | List     | List of additional [build contexts](https://docs.docker.com/engine/reference/commandline/buildx_build/#build-context) (e.g., `name=path`)                                         |
 | 
			
		||||
| `cache-from`       | List     | List of [external cache sources](https://docs.docker.com/engine/reference/commandline/buildx_build/#cache-from) (e.g., `type=local,src=path/to/dir`)                              |
 | 
			
		||||
| `cache-to`         | List     | List of [cache export destinations](https://docs.docker.com/engine/reference/commandline/buildx_build/#cache-to) (e.g., `type=local,dest=path/to/dir`)                            |
 | 
			
		||||
| `cgroup-parent`    | String   | Optional [parent cgroup](https://docs.docker.com/engine/reference/commandline/build/#use-a-custom-parent-cgroup---cgroup-parent) for the container used in the build              |
 | 
			
		||||
| `context`          | String   | Build's context is the set of files located in the specified [`PATH` or `URL`](https://docs.docker.com/engine/reference/commandline/build/) (default [Git context](#git-context)) |
 | 
			
		||||
| `file`             | String   | Path to the Dockerfile. (default `{context}/Dockerfile`)                                                                                                                          |
 | 
			
		||||
| `labels`           | List     | List of metadata for an image                                                                                                                                                     |
 | 
			
		||||
| `load`             | Bool     | [Load](https://docs.docker.com/engine/reference/commandline/buildx_build/#load) is a shorthand for `--output=type=docker` (default `false`)                                       |
 | 
			
		||||
| `network`          | String   | Set the networking mode for the `RUN` instructions during build                                                                                                                   |
 | 
			
		||||
| `no-cache`         | Bool     | Do not use cache when building the image (default `false`)                                                                                                                        |
 | 
			
		||||
| `no-cache-filters` | List/CSV | Do not cache specified stages                                                                                                                                                     |
 | 
			
		||||
| `outputs`¹         | List     | List of [output destinations](https://docs.docker.com/engine/reference/commandline/buildx_build/#output) (format: `type=local,dest=path`)                                         |
 | 
			
		||||
| `platforms`        | List/CSV | List of [target platforms](https://docs.docker.com/engine/reference/commandline/buildx_build/#platform) for build                                                                 |
 | 
			
		||||
| `pull`             | Bool     | Always attempt to pull all referenced images (default `false`)                                                                                                                    |
 | 
			
		||||
| `push`             | Bool     | [Push](https://docs.docker.com/engine/reference/commandline/buildx_build/#push) is a shorthand for `--output=type=registry` (default `false`)                                     |
 | 
			
		||||
| `secrets`          | List     | List of [secrets](https://docs.docker.com/engine/reference/commandline/buildx_build/#secret) to expose to the build (e.g., `key=string`, `GIT_AUTH_TOKEN=mytoken`)                |
 | 
			
		||||
| `secret-files`     | List     | List of [secret files](https://docs.docker.com/engine/reference/commandline/buildx_build/#secret) to expose to the build (e.g., `key=filename`, `MY_SECRET=./secret.txt`)         |
 | 
			
		||||
| `shm-size`         | String   | Size of [`/dev/shm`](https://docs.docker.com/engine/reference/commandline/buildx_build/#shm-size) (e.g., `2g`)                                                                    |
 | 
			
		||||
| `ssh`              | List     | List of [SSH agent socket or keys](https://docs.docker.com/engine/reference/commandline/buildx_build/#ssh) to expose to the build                                                 |
 | 
			
		||||
| `tags`             | List/CSV | List of tags                                                                                                                                                                      |
 | 
			
		||||
| `target`           | String   | Sets the target stage to build                                                                                                                                                    |
 | 
			
		||||
| `ulimit`           | List     | [Ulimit](https://docs.docker.com/engine/reference/commandline/buildx_build/#ulimit) options (e.g., `nofile=1024:1024`)                                                            |
 | 
			
		||||
| `github-token`     | String   | GitHub Token used to authenticate against a repository for [Git context](#git-context) (default `${{ github.token }}`)                                                            |
 | 
			
		||||
| Name               | Type        | Description                                                                                                                                                                       |
 | 
			
		||||
|--------------------|-------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
 | 
			
		||||
| `add-hosts`        | List/CSV    | List of [customs host-to-IP mapping](https://docs.docker.com/engine/reference/commandline/build/#add-entries-to-container-hosts-file---add-host) (e.g., `docker:10.180.0.1`)      |
 | 
			
		||||
| `allow`            | List/CSV    | List of [extra privileged entitlement](https://docs.docker.com/engine/reference/commandline/buildx_build/#allow) (e.g., `network.host,security.insecure`)                         |
 | 
			
		||||
| `attests`          | List        | List of [attestation](https://docs.docker.com/build/attestations/) parameters (e.g., `type=sbom,generator=image`)                                                                 | 
 | 
			
		||||
| `builder`          | String      | Builder instance (see [setup-buildx](https://github.com/docker/setup-buildx-action) action)                                                                                       |
 | 
			
		||||
| `build-args`       | List        | List of [build-time variables](https://docs.docker.com/engine/reference/commandline/buildx_build/#build-arg)                                                                      |
 | 
			
		||||
| `build-contexts`   | List        | List of additional [build contexts](https://docs.docker.com/engine/reference/commandline/buildx_build/#build-context) (e.g., `name=path`)                                         |
 | 
			
		||||
| `cache-from`       | List        | List of [external cache sources](https://docs.docker.com/engine/reference/commandline/buildx_build/#cache-from) (e.g., `type=local,src=path/to/dir`)                              |
 | 
			
		||||
| `cache-to`         | List        | List of [cache export destinations](https://docs.docker.com/engine/reference/commandline/buildx_build/#cache-to) (e.g., `type=local,dest=path/to/dir`)                            |
 | 
			
		||||
| `cgroup-parent`    | String      | Optional [parent cgroup](https://docs.docker.com/engine/reference/commandline/build/#use-a-custom-parent-cgroup---cgroup-parent) for the container used in the build              |
 | 
			
		||||
| `context`          | String      | Build's context is the set of files located in the specified [`PATH` or `URL`](https://docs.docker.com/engine/reference/commandline/build/) (default [Git context](#git-context)) |
 | 
			
		||||
| `file`             | String      | Path to the Dockerfile. (default `{context}/Dockerfile`)                                                                                                                          |
 | 
			
		||||
| `labels`           | List        | List of metadata for an image                                                                                                                                                     |
 | 
			
		||||
| `load`             | Bool        | [Load](https://docs.docker.com/engine/reference/commandline/buildx_build/#load) is a shorthand for `--output=type=docker` (default `false`)                                       |
 | 
			
		||||
| `network`          | String      | Set the networking mode for the `RUN` instructions during build                                                                                                                   |
 | 
			
		||||
| `no-cache`         | Bool        | Do not use cache when building the image (default `false`)                                                                                                                        |
 | 
			
		||||
| `no-cache-filters` | List/CSV    | Do not cache specified stages                                                                                                                                                     |
 | 
			
		||||
| `outputs`¹         | List        | List of [output destinations](https://docs.docker.com/engine/reference/commandline/buildx_build/#output) (format: `type=local,dest=path`)                                         |
 | 
			
		||||
| `platforms`        | List/CSV    | List of [target platforms](https://docs.docker.com/engine/reference/commandline/buildx_build/#platform) for build                                                                 |
 | 
			
		||||
| `provenance`       | Bool/String | Generate [provenance](https://docs.docker.com/build/attestations/slsa-provenance/) attestation for the build (shorthand for `--attest=type=provenance`)                           |
 | 
			
		||||
| `pull`             | Bool        | Always attempt to pull all referenced images (default `false`)                                                                                                                    |
 | 
			
		||||
| `push`             | Bool        | [Push](https://docs.docker.com/engine/reference/commandline/buildx_build/#push) is a shorthand for `--output=type=registry` (default `false`)                                     |
 | 
			
		||||
| `sbom`             | Bool/String | Generate [SBOM](https://docs.docker.com/build/attestations/sbom/) attestation for the build (shorthand for `--attest=type=sbom`)                                                  |
 | 
			
		||||
| `secrets`          | List        | List of [secrets](https://docs.docker.com/engine/reference/commandline/buildx_build/#secret) to expose to the build (e.g., `key=string`, `GIT_AUTH_TOKEN=mytoken`)                |
 | 
			
		||||
| `secret-files`     | List        | List of [secret files](https://docs.docker.com/engine/reference/commandline/buildx_build/#secret) to expose to the build (e.g., `key=filename`, `MY_SECRET=./secret.txt`)         |
 | 
			
		||||
| `shm-size`         | String      | Size of [`/dev/shm`](https://docs.docker.com/engine/reference/commandline/buildx_build/#shm-size) (e.g., `2g`)                                                                    |
 | 
			
		||||
| `ssh`              | List        | List of [SSH agent socket or keys](https://docs.docker.com/engine/reference/commandline/buildx_build/#ssh) to expose to the build                                                 |
 | 
			
		||||
| `tags`             | List/CSV    | List of tags                                                                                                                                                                      |
 | 
			
		||||
| `target`           | String      | Sets the target stage to build                                                                                                                                                    |
 | 
			
		||||
| `ulimit`           | List        | [Ulimit](https://docs.docker.com/engine/reference/commandline/buildx_build/#ulimit) options (e.g., `nofile=1024:1024`)                                                            |
 | 
			
		||||
| `github-token`     | String      | GitHub Token used to authenticate against a repository for [Git context](#git-context) (default `${{ github.token }}`)                                                            |
 | 
			
		||||
 | 
			
		||||
> **Note**
 | 
			
		||||
>
 | 
			
		||||
 | 
			
		||||
@ -13,6 +13,9 @@ inputs:
 | 
			
		||||
  allow:
 | 
			
		||||
    description: "List of extra privileged entitlement (e.g., network.host,security.insecure)"
 | 
			
		||||
    required: false
 | 
			
		||||
  attests:
 | 
			
		||||
    description: "List of attestation parameters (e.g., type=sbom,generator=image)"
 | 
			
		||||
    required: false
 | 
			
		||||
  build-args:
 | 
			
		||||
    description: "List of build-time variables"
 | 
			
		||||
    required: false
 | 
			
		||||
@ -60,6 +63,9 @@ inputs:
 | 
			
		||||
  platforms:
 | 
			
		||||
    description: "List of target platforms for build"
 | 
			
		||||
    required: false
 | 
			
		||||
  provenance:
 | 
			
		||||
    description: "Generate provenance attestation for the build (shorthand for --attest=type=provenance)"
 | 
			
		||||
    required: false
 | 
			
		||||
  pull:
 | 
			
		||||
    description: "Always attempt to pull all referenced images"
 | 
			
		||||
    required: false
 | 
			
		||||
@ -68,6 +74,9 @@ inputs:
 | 
			
		||||
    description: "Push is a shorthand for --output=type=registry"
 | 
			
		||||
    required: false
 | 
			
		||||
    default: 'false'
 | 
			
		||||
  sbom:
 | 
			
		||||
    description: "Generate SBOM attestation for the build (shorthand for --attest=type=sbom)"
 | 
			
		||||
    required: false
 | 
			
		||||
  secrets:
 | 
			
		||||
    description: "List of secrets to expose to the build (e.g., key=string, GIT_AUTH_TOKEN=mytoken)"
 | 
			
		||||
    required: false
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										6
									
								
								dist/index.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								dist/index.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/index.js.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/index.js.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										123
									
								
								src/buildx.ts
									
									
									
									
									
								
							
							
						
						
									
										123
									
								
								src/buildx.ts
									
									
									
									
									
								
							@ -3,9 +3,24 @@ import fs from 'fs';
 | 
			
		||||
import path from 'path';
 | 
			
		||||
import * as semver from 'semver';
 | 
			
		||||
import * as exec from '@actions/exec';
 | 
			
		||||
 | 
			
		||||
import * as context from './context';
 | 
			
		||||
 | 
			
		||||
export type Builder = {
 | 
			
		||||
  name?: string;
 | 
			
		||||
  driver?: string;
 | 
			
		||||
  nodes: Node[];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export type Node = {
 | 
			
		||||
  name?: string;
 | 
			
		||||
  endpoint?: string;
 | 
			
		||||
  'driver-opts'?: Array<string>;
 | 
			
		||||
  status?: string;
 | 
			
		||||
  'buildkitd-flags'?: string;
 | 
			
		||||
  buildkit?: string;
 | 
			
		||||
  platforms?: string;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export async function getImageIDFile(): Promise<string> {
 | 
			
		||||
  return path.join(context.tmpDir(), 'iidfile').split(path.sep).join(path.posix.sep);
 | 
			
		||||
}
 | 
			
		||||
@ -126,6 +141,112 @@ export async function isAvailable(standalone?: boolean): Promise<boolean> {
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function satisfiesBuildKitVersion(builderName: string, range: string, standalone?: boolean): Promise<boolean> {
 | 
			
		||||
  const builderInspect = await inspect(builderName, standalone);
 | 
			
		||||
  for (const node of builderInspect.nodes) {
 | 
			
		||||
    if (!node.buildkit) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    // BuildKit version reported by moby is in the format of `v0.11.0-moby`
 | 
			
		||||
    if (builderInspect.driver == 'docker' && !node.buildkit.endsWith('-moby')) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    const version = node.buildkit.replace(/-moby$/, '');
 | 
			
		||||
    if (!semver.satisfies(version, range)) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function inspect(name: string, standalone?: boolean): Promise<Builder> {
 | 
			
		||||
  const cmd = getCommand(['inspect', name], standalone);
 | 
			
		||||
  return await exec
 | 
			
		||||
    .getExecOutput(cmd.command, cmd.args, {
 | 
			
		||||
      ignoreReturnCode: true,
 | 
			
		||||
      silent: true
 | 
			
		||||
    })
 | 
			
		||||
    .then(res => {
 | 
			
		||||
      if (res.stderr.length > 0 && res.exitCode != 0) {
 | 
			
		||||
        throw new Error(res.stderr.trim());
 | 
			
		||||
      }
 | 
			
		||||
      return parseInspect(res.stdout);
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function parseInspect(data: string): Promise<Builder> {
 | 
			
		||||
  const builder: Builder = {
 | 
			
		||||
    nodes: []
 | 
			
		||||
  };
 | 
			
		||||
  let node: Node = {};
 | 
			
		||||
  for (const line of data.trim().split(`\n`)) {
 | 
			
		||||
    const [key, ...rest] = line.split(':');
 | 
			
		||||
    const value = rest.map(v => v.trim()).join(':');
 | 
			
		||||
    if (key.length == 0 || value.length == 0) {
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
    switch (key.toLowerCase()) {
 | 
			
		||||
      case 'name': {
 | 
			
		||||
        if (builder.name == undefined) {
 | 
			
		||||
          builder.name = value;
 | 
			
		||||
        } else {
 | 
			
		||||
          if (Object.keys(node).length > 0) {
 | 
			
		||||
            builder.nodes.push(node);
 | 
			
		||||
            node = {};
 | 
			
		||||
          }
 | 
			
		||||
          node.name = value;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      case 'driver': {
 | 
			
		||||
        builder.driver = value;
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      case 'endpoint': {
 | 
			
		||||
        node.endpoint = value;
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      case 'driver options': {
 | 
			
		||||
        node['driver-opts'] = (value.match(/(\w+)="([^"]*)"/g) || []).map(v => v.replace(/^(.*)="(.*)"$/g, '$1=$2'));
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      case 'status': {
 | 
			
		||||
        node.status = value;
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      case 'flags': {
 | 
			
		||||
        node['buildkitd-flags'] = value;
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      case 'buildkit': {
 | 
			
		||||
        node.buildkit = value;
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      case 'platforms': {
 | 
			
		||||
        let platforms: Array<string> = [];
 | 
			
		||||
        // if a preferred platform is being set then use only these
 | 
			
		||||
        // https://docs.docker.com/engine/reference/commandline/buildx_inspect/#get-information-about-a-builder-instance
 | 
			
		||||
        if (value.includes('*')) {
 | 
			
		||||
          for (const platform of value.split(', ')) {
 | 
			
		||||
            if (platform.includes('*')) {
 | 
			
		||||
              platforms.push(platform.replace('*', ''));
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        } else {
 | 
			
		||||
          // otherwise set all platforms available
 | 
			
		||||
          platforms = value.split(', ');
 | 
			
		||||
        }
 | 
			
		||||
        node.platforms = platforms.join(',');
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  if (Object.keys(node).length > 0) {
 | 
			
		||||
    builder.nodes.push(node);
 | 
			
		||||
  }
 | 
			
		||||
  return builder;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function getVersion(standalone?: boolean): Promise<string> {
 | 
			
		||||
  const cmd = getCommand(['version'], standalone);
 | 
			
		||||
  return await exec
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										102
									
								
								src/context.ts
									
									
									
									
									
								
							
							
						
						
									
										102
									
								
								src/context.ts
									
									
									
									
									
								
							@ -13,6 +13,7 @@ let _defaultContext, _tmpDir: string;
 | 
			
		||||
export interface Inputs {
 | 
			
		||||
  addHosts: string[];
 | 
			
		||||
  allow: string[];
 | 
			
		||||
  attests: string[];
 | 
			
		||||
  buildArgs: string[];
 | 
			
		||||
  buildContexts: string[];
 | 
			
		||||
  builder: string;
 | 
			
		||||
@ -28,8 +29,10 @@ export interface Inputs {
 | 
			
		||||
  noCacheFilters: string[];
 | 
			
		||||
  outputs: string[];
 | 
			
		||||
  platforms: string[];
 | 
			
		||||
  provenance: string;
 | 
			
		||||
  pull: boolean;
 | 
			
		||||
  push: boolean;
 | 
			
		||||
  sbom: string;
 | 
			
		||||
  secrets: string[];
 | 
			
		||||
  secretFiles: string[];
 | 
			
		||||
  shmSize: string;
 | 
			
		||||
@ -69,6 +72,7 @@ export async function getInputs(defaultContext: string): Promise<Inputs> {
 | 
			
		||||
  return {
 | 
			
		||||
    addHosts: await getInputList('add-hosts'),
 | 
			
		||||
    allow: await getInputList('allow'),
 | 
			
		||||
    attests: await getInputList('attests', true),
 | 
			
		||||
    buildArgs: await getInputList('build-args', true),
 | 
			
		||||
    buildContexts: await getInputList('build-contexts', true),
 | 
			
		||||
    builder: core.getInput('builder'),
 | 
			
		||||
@ -84,8 +88,10 @@ export async function getInputs(defaultContext: string): Promise<Inputs> {
 | 
			
		||||
    noCacheFilters: await getInputList('no-cache-filters'),
 | 
			
		||||
    outputs: await getInputList('outputs', true),
 | 
			
		||||
    platforms: await getInputList('platforms'),
 | 
			
		||||
    provenance: core.getInput('provenance'),
 | 
			
		||||
    pull: core.getBooleanInput('pull'),
 | 
			
		||||
    push: core.getBooleanInput('push'),
 | 
			
		||||
    sbom: core.getInput('sbom'),
 | 
			
		||||
    secrets: await getInputList('secrets', true),
 | 
			
		||||
    secretFiles: await getInputList('secret-files', true),
 | 
			
		||||
    shmSize: core.getInput('shm-size'),
 | 
			
		||||
@ -97,17 +103,17 @@ export async function getInputs(defaultContext: string): Promise<Inputs> {
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function getArgs(inputs: Inputs, defaultContext: string, buildxVersion: string): Promise<Array<string>> {
 | 
			
		||||
export async function getArgs(inputs: Inputs, defaultContext: string, buildxVersion: string, standalone?: boolean): Promise<Array<string>> {
 | 
			
		||||
  const context = handlebars.compile(inputs.context)({defaultContext});
 | 
			
		||||
  // prettier-ignore
 | 
			
		||||
  return [
 | 
			
		||||
    ...await getBuildArgs(inputs, defaultContext, context, buildxVersion),
 | 
			
		||||
    ...await getBuildArgs(inputs, defaultContext, context, buildxVersion, standalone),
 | 
			
		||||
    ...await getCommonArgs(inputs, buildxVersion),
 | 
			
		||||
    context
 | 
			
		||||
  ];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function getBuildArgs(inputs: Inputs, defaultContext: string, context: string, buildxVersion: string): Promise<Array<string>> {
 | 
			
		||||
async function getBuildArgs(inputs: Inputs, defaultContext: string, context: string, buildxVersion: string, standalone?: boolean): Promise<Array<string>> {
 | 
			
		||||
  const args: Array<string> = ['build'];
 | 
			
		||||
  await asyncForEach(inputs.addHosts, async addHost => {
 | 
			
		||||
    args.push('--add-host', addHost);
 | 
			
		||||
@ -115,6 +121,11 @@ async function getBuildArgs(inputs: Inputs, defaultContext: string, context: str
 | 
			
		||||
  if (inputs.allow.length > 0) {
 | 
			
		||||
    args.push('--allow', inputs.allow.join(','));
 | 
			
		||||
  }
 | 
			
		||||
  if (buildx.satisfies(buildxVersion, '>=0.10.0')) {
 | 
			
		||||
    await asyncForEach(inputs.attests, async attest => {
 | 
			
		||||
      args.push('--attest', attest);
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
  await asyncForEach(inputs.buildArgs, async buildArg => {
 | 
			
		||||
    args.push('--build-arg', buildArg);
 | 
			
		||||
  });
 | 
			
		||||
@ -150,6 +161,29 @@ async function getBuildArgs(inputs: Inputs, defaultContext: string, context: str
 | 
			
		||||
  if (inputs.platforms.length > 0) {
 | 
			
		||||
    args.push('--platform', inputs.platforms.join(','));
 | 
			
		||||
  }
 | 
			
		||||
  if (buildx.satisfies(buildxVersion, '>=0.10.0')) {
 | 
			
		||||
    const prvBuilderID = `${process.env.GITHUB_SERVER_URL || 'https://github.com'}/${github.context.repo.owner}/${github.context.repo.repo}/actions/runs/${github.context.runId}`;
 | 
			
		||||
    if (inputs.provenance) {
 | 
			
		||||
      args.push('--provenance', getProvenanceAttrs(inputs.provenance, prvBuilderID));
 | 
			
		||||
    } else if ((await buildx.satisfiesBuildKitVersion(inputs.builder, '>=0.11.0', standalone)) && !hasDockerExport(inputs)) {
 | 
			
		||||
      // if provenance not specified and BuildKit version compatible for
 | 
			
		||||
      // attestation, set default provenance. Also needs to make sure user
 | 
			
		||||
      // doesn't want to explicitly load the image to docker.
 | 
			
		||||
      if (fromPayload('repository.private') !== false) {
 | 
			
		||||
        // if this is a private repository, we set the default provenance
 | 
			
		||||
        // attributes being set in buildx: https://github.com/docker/buildx/blob/fb27e3f919dcbf614d7126b10c2bc2d0b1927eb6/build/build.go#L603
 | 
			
		||||
        // along the builder-id attribute.
 | 
			
		||||
        args.push('--provenance', `mode=min,inline-only=true,builder-id=${prvBuilderID}`);
 | 
			
		||||
      } else {
 | 
			
		||||
        // for a public repository, we set max provenance mode and the
 | 
			
		||||
        // builder-id attribute.
 | 
			
		||||
        args.push('--provenance', `mode=max,builder-id=${prvBuilderID}`);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (inputs.sbom) {
 | 
			
		||||
      args.push('--sbom', inputs.sbom);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  await asyncForEach(inputs.secrets, async secret => {
 | 
			
		||||
    try {
 | 
			
		||||
      args.push('--secret', await buildx.getSecretString(secret));
 | 
			
		||||
@ -245,3 +279,65 @@ export const asyncForEach = async (array, callback) => {
 | 
			
		||||
    await callback(array[index], index, array);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
 | 
			
		||||
function fromPayload(path: string): any {
 | 
			
		||||
  return select(github.context.payload, path);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
 | 
			
		||||
function select(obj: any, path: string): any {
 | 
			
		||||
  if (!obj) {
 | 
			
		||||
    return undefined;
 | 
			
		||||
  }
 | 
			
		||||
  const i = path.indexOf('.');
 | 
			
		||||
  if (i < 0) {
 | 
			
		||||
    return obj[path];
 | 
			
		||||
  }
 | 
			
		||||
  const key = path.slice(0, i);
 | 
			
		||||
  return select(obj[key], path.slice(i + 1));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getProvenanceAttrs(input: string, builderID: string): string {
 | 
			
		||||
  const fields = parse(input, {
 | 
			
		||||
    relaxColumnCount: true,
 | 
			
		||||
    skipEmptyLines: true
 | 
			
		||||
  })[0];
 | 
			
		||||
  // check if builder-id attribute exists in the input
 | 
			
		||||
  for (const field of fields) {
 | 
			
		||||
    const parts = field
 | 
			
		||||
      .toString()
 | 
			
		||||
      .split(/(?<=^[^=]+?)=/)
 | 
			
		||||
      .map(item => item.trim());
 | 
			
		||||
    if (parts[0] == 'builder-id') {
 | 
			
		||||
      return input;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // if not add builder-id attribute
 | 
			
		||||
  return `${input},builder-id=${builderID}`;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function hasDockerExport(inputs: Inputs): boolean {
 | 
			
		||||
  if (inputs.load) {
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  for (const output of inputs.outputs) {
 | 
			
		||||
    const fields = parse(output, {
 | 
			
		||||
      relaxColumnCount: true,
 | 
			
		||||
      skipEmptyLines: true
 | 
			
		||||
    })[0];
 | 
			
		||||
    for (const field of fields) {
 | 
			
		||||
      const parts = field
 | 
			
		||||
        .toString()
 | 
			
		||||
        .split(/(?<=^[^=]+?)=/)
 | 
			
		||||
        .map(item => item.trim());
 | 
			
		||||
      if (parts.length != 2) {
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
      if (parts[0] == 'type' && parts[1] == 'docker') {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -41,7 +41,7 @@ async function run(): Promise<void> {
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    const args: string[] = await context.getArgs(inputs, defContext, buildxVersion);
 | 
			
		||||
    const args: string[] = await context.getArgs(inputs, defContext, buildxVersion, standalone);
 | 
			
		||||
    const buildCmd = buildx.getCommand(args, standalone);
 | 
			
		||||
    await exec
 | 
			
		||||
      .getExecOutput(buildCmd.command, buildCmd.args, {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										16
									
								
								test/go/Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								test/go/Dockerfile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
			
		||||
FROM golang:1.19-alpine AS base
 | 
			
		||||
ENV CGO_ENABLED=0
 | 
			
		||||
RUN apk add --no-cache file git
 | 
			
		||||
WORKDIR /src
 | 
			
		||||
 | 
			
		||||
FROM base as build
 | 
			
		||||
COPY go.mod go.sum ./
 | 
			
		||||
RUN go mod download -x
 | 
			
		||||
COPY . .
 | 
			
		||||
RUN go build -ldflags "-s -w" -o /usr/bin/app .
 | 
			
		||||
 | 
			
		||||
FROM scratch AS binary
 | 
			
		||||
COPY --from=build /usr/bin/app /bin/app
 | 
			
		||||
 | 
			
		||||
FROM alpine:3.17 AS image
 | 
			
		||||
COPY --from=build /usr/bin/app /bin/app
 | 
			
		||||
							
								
								
									
										19
									
								
								test/go/go.mod
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								test/go/go.mod
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,19 @@
 | 
			
		||||
module github.com/docker/build-push-action/test/go
 | 
			
		||||
 | 
			
		||||
go 1.18
 | 
			
		||||
 | 
			
		||||
require github.com/labstack/echo/v4 v4.9.1
 | 
			
		||||
 | 
			
		||||
require (
 | 
			
		||||
	github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
 | 
			
		||||
	github.com/labstack/gommon v0.4.0 // indirect
 | 
			
		||||
	github.com/mattn/go-colorable v0.1.11 // indirect
 | 
			
		||||
	github.com/mattn/go-isatty v0.0.14 // indirect
 | 
			
		||||
	github.com/valyala/bytebufferpool v1.0.0 // indirect
 | 
			
		||||
	github.com/valyala/fasttemplate v1.2.1 // indirect
 | 
			
		||||
	golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
 | 
			
		||||
	golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f // indirect
 | 
			
		||||
	golang.org/x/sys v0.0.0-20211103235746-7861aae1554b // indirect
 | 
			
		||||
	golang.org/x/text v0.3.7 // indirect
 | 
			
		||||
	golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 // indirect
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										38
									
								
								test/go/go.sum
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								test/go/go.sum
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,38 @@
 | 
			
		||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
			
		||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 | 
			
		||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
			
		||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
 | 
			
		||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
 | 
			
		||||
github.com/labstack/echo/v4 v4.9.1 h1:GliPYSpzGKlyOhqIbG8nmHBo3i1saKWFOgh41AN3b+Y=
 | 
			
		||||
github.com/labstack/echo/v4 v4.9.1/go.mod h1:Pop5HLc+xoc4qhTZ1ip6C0RtP7Z+4VzRLWZZFKqbbjo=
 | 
			
		||||
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
 | 
			
		||||
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
 | 
			
		||||
github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs=
 | 
			
		||||
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
 | 
			
		||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
 | 
			
		||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
 | 
			
		||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 | 
			
		||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 | 
			
		||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 | 
			
		||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
 | 
			
		||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 | 
			
		||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
 | 
			
		||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
 | 
			
		||||
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
 | 
			
		||||
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 | 
			
		||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f h1:OfiFi4JbukWwe3lzw+xunroH1mnC1e2Gy5cxNJApiSY=
 | 
			
		||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 | 
			
		||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b h1:1VkfZQv42XQlA/jchYumAnv1UPo6RgF9rJFkTgZIxO4=
 | 
			
		||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
 | 
			
		||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 | 
			
		||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 h1:Hir2P/De0WpUhtrKGGjvSb2YxUgyZ7EFOSLIcSSpiwE=
 | 
			
		||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 | 
			
		||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
			
		||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 | 
			
		||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
 | 
			
		||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 | 
			
		||||
							
								
								
									
										31
									
								
								test/go/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								test/go/main.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"os"
 | 
			
		||||
 | 
			
		||||
	"github.com/labstack/echo/v4"
 | 
			
		||||
	"github.com/labstack/echo/v4/middleware"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	e := echo.New()
 | 
			
		||||
 | 
			
		||||
	e.Use(middleware.Logger())
 | 
			
		||||
	e.Use(middleware.Recover())
 | 
			
		||||
 | 
			
		||||
	e.GET("/", func(c echo.Context) error {
 | 
			
		||||
		return c.HTML(http.StatusOK, "Hello World")
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	e.GET("/ping", func(c echo.Context) error {
 | 
			
		||||
		return c.JSON(http.StatusOK, struct{ Status string }{Status: "OK"})
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	httpPort := os.Getenv("HTTP_PORT")
 | 
			
		||||
	if httpPort == "" {
 | 
			
		||||
		httpPort = "8080"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	e.Logger.Fatal(e.Start(":" + httpPort))
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user