mirror of
				https://github.com/docker/build-push-action.git
				synced 2025-11-04 00:10:55 +00:00 
			
		
		
		
	Merge pull request #759 from crazy-max/fix-provenance-input
Fix provenance input
This commit is contained in:
		
				commit
				
					
						d1b0eb0a29
					
				
			
		
					 6 changed files with 188 additions and 13 deletions
				
			
		
							
								
								
									
										35
									
								
								.github/workflows/ci.yml
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										35
									
								
								.github/workflows/ci.yml
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -523,6 +523,41 @@ jobs:
 | 
				
			||||||
          file: ./test/go/Dockerfile
 | 
					          file: ./test/go/Dockerfile
 | 
				
			||||||
          outputs: type=cacheonly
 | 
					          outputs: type=cacheonly
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  provenance:
 | 
				
			||||||
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
 | 
					    strategy:
 | 
				
			||||||
 | 
					      fail-fast: false
 | 
				
			||||||
 | 
					      matrix:
 | 
				
			||||||
 | 
					        attrs:
 | 
				
			||||||
 | 
					          - ''
 | 
				
			||||||
 | 
					          - mode=max
 | 
				
			||||||
 | 
					          - builder-id=foo
 | 
				
			||||||
 | 
					          - false
 | 
				
			||||||
 | 
					          - true
 | 
				
			||||||
 | 
					    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: binary
 | 
				
			||||||
 | 
					          outputs: type=oci,dest=/tmp/build.tar
 | 
				
			||||||
 | 
					          provenance: ${{ matrix.attrs }}
 | 
				
			||||||
 | 
					          cache-from: type=gha,scope=provenance
 | 
				
			||||||
 | 
					          cache-to: type=gha,scope=provenance,mode=max
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  sbom:
 | 
					  sbom:
 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
    strategy:
 | 
					    strategy:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,7 @@ import {beforeEach, describe, expect, it, jest, test} from '@jest/globals';
 | 
				
			||||||
import * as fs from 'fs';
 | 
					import * as fs from 'fs';
 | 
				
			||||||
import * as path from 'path';
 | 
					import * as path from 'path';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import * as buildx from '../src/buildx';
 | 
				
			||||||
import * as context from '../src/context';
 | 
					import * as context from '../src/context';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const pgp = `-----BEGIN PGP PRIVATE KEY BLOCK-----
 | 
					const pgp = `-----BEGIN PGP PRIVATE KEY BLOCK-----
 | 
				
			||||||
| 
						 | 
					@ -127,6 +128,8 @@ jest.spyOn(context, 'tmpNameSync').mockImplementation((): string => {
 | 
				
			||||||
  return path.join('/tmp/.docker-build-push-jest', '.tmpname-jest').split(path.sep).join(path.posix.sep);
 | 
					  return path.join('/tmp/.docker-build-push-jest', '.tmpname-jest').split(path.sep).join(path.posix.sep);
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					jest.spyOn(buildx, 'satisfiesBuildKitVersion').mockResolvedValueOnce(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('getArgs', () => {
 | 
					describe('getArgs', () => {
 | 
				
			||||||
  beforeEach(() => {
 | 
					  beforeEach(() => {
 | 
				
			||||||
    process.env = Object.keys(process.env).reduce((object, key) => {
 | 
					    process.env = Object.keys(process.env).reduce((object, key) => {
 | 
				
			||||||
| 
						 | 
					@ -159,7 +162,11 @@ describe('getArgs', () => {
 | 
				
			||||||
      1,
 | 
					      1,
 | 
				
			||||||
      '0.4.2',
 | 
					      '0.4.2',
 | 
				
			||||||
      new Map<string, string>([
 | 
					      new Map<string, string>([
 | 
				
			||||||
        ['build-args', 'MY_ARG=val1,val2,val3\nARG=val'],
 | 
					        ['build-args', `MY_ARG=val1,val2,val3
 | 
				
			||||||
 | 
					ARG=val
 | 
				
			||||||
 | 
					"MULTILINE=aaaa
 | 
				
			||||||
 | 
					bbbb
 | 
				
			||||||
 | 
					ccc"`],
 | 
				
			||||||
        ['load', 'false'],
 | 
					        ['load', 'false'],
 | 
				
			||||||
        ['no-cache', 'false'],
 | 
					        ['no-cache', 'false'],
 | 
				
			||||||
        ['push', 'false'],
 | 
					        ['push', 'false'],
 | 
				
			||||||
| 
						 | 
					@ -169,6 +176,7 @@ describe('getArgs', () => {
 | 
				
			||||||
        'build',
 | 
					        'build',
 | 
				
			||||||
        '--build-arg', 'MY_ARG=val1,val2,val3',
 | 
					        '--build-arg', 'MY_ARG=val1,val2,val3',
 | 
				
			||||||
        '--build-arg', 'ARG=val',
 | 
					        '--build-arg', 'ARG=val',
 | 
				
			||||||
 | 
					        '--build-arg', `MULTILINE=aaaa\nbbbb\nccc`,
 | 
				
			||||||
        '--iidfile', '/tmp/.docker-build-push-jest/iidfile',
 | 
					        '--iidfile', '/tmp/.docker-build-push-jest/iidfile',
 | 
				
			||||||
        'https://github.com/docker/build-push-action.git#refs/heads/test-jest'
 | 
					        'https://github.com/docker/build-push-action.git#refs/heads/test-jest'
 | 
				
			||||||
      ]
 | 
					      ]
 | 
				
			||||||
| 
						 | 
					@ -517,7 +525,119 @@ nproc=3`],
 | 
				
			||||||
        '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file',
 | 
					        '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file',
 | 
				
			||||||
        'https://github.com/docker/build-push-action.git#refs/heads/test-jest:subdir'
 | 
					        'https://github.com/docker/build-push-action.git#refs/heads/test-jest:subdir'
 | 
				
			||||||
      ]
 | 
					      ]
 | 
				
			||||||
    ]
 | 
					    ],
 | 
				
			||||||
 | 
					    [
 | 
				
			||||||
 | 
					      17,
 | 
				
			||||||
 | 
					      '0.8.2',
 | 
				
			||||||
 | 
					      new Map<string, string>([
 | 
				
			||||||
 | 
					        ['context', '.'],
 | 
				
			||||||
 | 
					        ['load', 'false'],
 | 
				
			||||||
 | 
					        ['no-cache', 'false'],
 | 
				
			||||||
 | 
					        ['push', 'false'],
 | 
				
			||||||
 | 
					        ['pull', 'false'],
 | 
				
			||||||
 | 
					        ['provenance', 'true'],
 | 
				
			||||||
 | 
					      ]),
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        'build',
 | 
				
			||||||
 | 
					        '--iidfile', '/tmp/.docker-build-push-jest/iidfile',
 | 
				
			||||||
 | 
					        '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file',
 | 
				
			||||||
 | 
					        '.'
 | 
				
			||||||
 | 
					      ]
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    [
 | 
				
			||||||
 | 
					      18,
 | 
				
			||||||
 | 
					      '0.10.0',
 | 
				
			||||||
 | 
					      new Map<string, string>([
 | 
				
			||||||
 | 
					        ['context', '.'],
 | 
				
			||||||
 | 
					        ['load', 'false'],
 | 
				
			||||||
 | 
					        ['no-cache', 'false'],
 | 
				
			||||||
 | 
					        ['push', 'false'],
 | 
				
			||||||
 | 
					        ['pull', 'false'],
 | 
				
			||||||
 | 
					      ]),
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        'build',
 | 
				
			||||||
 | 
					        '--iidfile', '/tmp/.docker-build-push-jest/iidfile',
 | 
				
			||||||
 | 
					        "--provenance", `mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
 | 
				
			||||||
 | 
					        '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file',
 | 
				
			||||||
 | 
					        '.'
 | 
				
			||||||
 | 
					      ]
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    [
 | 
				
			||||||
 | 
					      19,
 | 
				
			||||||
 | 
					      '0.10.0',
 | 
				
			||||||
 | 
					      new Map<string, string>([
 | 
				
			||||||
 | 
					        ['context', '.'],
 | 
				
			||||||
 | 
					        ['load', 'false'],
 | 
				
			||||||
 | 
					        ['no-cache', 'false'],
 | 
				
			||||||
 | 
					        ['push', 'false'],
 | 
				
			||||||
 | 
					        ['pull', 'false'],
 | 
				
			||||||
 | 
					        ['provenance', 'true'],
 | 
				
			||||||
 | 
					      ]),
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        'build',
 | 
				
			||||||
 | 
					        '--iidfile', '/tmp/.docker-build-push-jest/iidfile',
 | 
				
			||||||
 | 
					        "--provenance", `builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
 | 
				
			||||||
 | 
					        '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file',
 | 
				
			||||||
 | 
					        '.'
 | 
				
			||||||
 | 
					      ]
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    [
 | 
				
			||||||
 | 
					      20,
 | 
				
			||||||
 | 
					      '0.10.0',
 | 
				
			||||||
 | 
					      new Map<string, string>([
 | 
				
			||||||
 | 
					        ['context', '.'],
 | 
				
			||||||
 | 
					        ['load', 'false'],
 | 
				
			||||||
 | 
					        ['no-cache', 'false'],
 | 
				
			||||||
 | 
					        ['push', 'false'],
 | 
				
			||||||
 | 
					        ['pull', 'false'],
 | 
				
			||||||
 | 
					        ['provenance', 'mode=max'],
 | 
				
			||||||
 | 
					      ]),
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        'build',
 | 
				
			||||||
 | 
					        '--iidfile', '/tmp/.docker-build-push-jest/iidfile',
 | 
				
			||||||
 | 
					        "--provenance", `mode=max,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789`,
 | 
				
			||||||
 | 
					        '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file',
 | 
				
			||||||
 | 
					        '.'
 | 
				
			||||||
 | 
					      ]
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    [
 | 
				
			||||||
 | 
					      21,
 | 
				
			||||||
 | 
					      '0.10.0',
 | 
				
			||||||
 | 
					      new Map<string, string>([
 | 
				
			||||||
 | 
					        ['context', '.'],
 | 
				
			||||||
 | 
					        ['load', 'false'],
 | 
				
			||||||
 | 
					        ['no-cache', 'false'],
 | 
				
			||||||
 | 
					        ['push', 'false'],
 | 
				
			||||||
 | 
					        ['pull', 'false'],
 | 
				
			||||||
 | 
					        ['provenance', 'false'],
 | 
				
			||||||
 | 
					      ]),
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        'build',
 | 
				
			||||||
 | 
					        '--iidfile', '/tmp/.docker-build-push-jest/iidfile',
 | 
				
			||||||
 | 
					        "--provenance", 'false',
 | 
				
			||||||
 | 
					        '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file',
 | 
				
			||||||
 | 
					        '.'
 | 
				
			||||||
 | 
					      ]
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    [
 | 
				
			||||||
 | 
					      22,
 | 
				
			||||||
 | 
					      '0.10.0',
 | 
				
			||||||
 | 
					      new Map<string, string>([
 | 
				
			||||||
 | 
					        ['context', '.'],
 | 
				
			||||||
 | 
					        ['load', 'false'],
 | 
				
			||||||
 | 
					        ['no-cache', 'false'],
 | 
				
			||||||
 | 
					        ['push', 'false'],
 | 
				
			||||||
 | 
					        ['pull', 'false'],
 | 
				
			||||||
 | 
					        ['provenance', 'builder-id=foo'],
 | 
				
			||||||
 | 
					      ]),
 | 
				
			||||||
 | 
					      [
 | 
				
			||||||
 | 
					        'build',
 | 
				
			||||||
 | 
					        '--iidfile', '/tmp/.docker-build-push-jest/iidfile',
 | 
				
			||||||
 | 
					        "--provenance", 'builder-id=foo',
 | 
				
			||||||
 | 
					        '--metadata-file', '/tmp/.docker-build-push-jest/metadata-file',
 | 
				
			||||||
 | 
					        '.'
 | 
				
			||||||
 | 
					      ]
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
  ])(
 | 
					  ])(
 | 
				
			||||||
    '[%d] given %p with %p as inputs, returns %p',
 | 
					    '[%d] given %p with %p as inputs, returns %p',
 | 
				
			||||||
    async (num: number, buildxVersion: string, inputs: Map<string, string>, expected: Array<string>) => {
 | 
					    async (num: number, buildxVersion: string, inputs: Map<string, string>, expected: Array<string>) => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,6 +68,8 @@ FROM docker/buildx-bin:${BUILDX_VERSION} as buildx
 | 
				
			||||||
FROM deps AS test
 | 
					FROM deps AS test
 | 
				
			||||||
ENV RUNNER_TEMP=/tmp/github_runner
 | 
					ENV RUNNER_TEMP=/tmp/github_runner
 | 
				
			||||||
ENV RUNNER_TOOL_CACHE=/tmp/github_tool_cache
 | 
					ENV RUNNER_TOOL_CACHE=/tmp/github_tool_cache
 | 
				
			||||||
 | 
					ENV GITHUB_REPOSITORY=docker/build-push-action
 | 
				
			||||||
 | 
					ENV GITHUB_RUN_ID=123456789
 | 
				
			||||||
RUN --mount=type=bind,target=.,rw \
 | 
					RUN --mount=type=bind,target=.,rw \
 | 
				
			||||||
  --mount=type=cache,target=/src/node_modules \
 | 
					  --mount=type=cache,target=/src/node_modules \
 | 
				
			||||||
  --mount=type=bind,from=docker,source=/usr/local/bin/docker,target=/usr/bin/docker \
 | 
					  --mount=type=bind,from=docker,source=/usr/local/bin/docker,target=/usr/bin/docker \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								dist/index.js
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								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
											
										
									
								
							| 
						 | 
					@ -68,6 +68,10 @@ export function tmpNameSync(options?: tmp.TmpNameOptions): string {
 | 
				
			||||||
  return tmp.tmpNameSync(options);
 | 
					  return tmp.tmpNameSync(options);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function provenanceBuilderID(): string {
 | 
				
			||||||
 | 
					  return `${process.env.GITHUB_SERVER_URL || 'https://github.com'}/${github.context.repo.owner}/${github.context.repo.repo}/actions/runs/${github.context.runId}`;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export async function getInputs(defaultContext: string): Promise<Inputs> {
 | 
					export async function getInputs(defaultContext: string): Promise<Inputs> {
 | 
				
			||||||
  return {
 | 
					  return {
 | 
				
			||||||
    addHosts: await getInputList('add-hosts'),
 | 
					    addHosts: await getInputList('add-hosts'),
 | 
				
			||||||
| 
						 | 
					@ -88,7 +92,7 @@ export async function getInputs(defaultContext: string): Promise<Inputs> {
 | 
				
			||||||
    noCacheFilters: await getInputList('no-cache-filters'),
 | 
					    noCacheFilters: await getInputList('no-cache-filters'),
 | 
				
			||||||
    outputs: await getInputList('outputs', true),
 | 
					    outputs: await getInputList('outputs', true),
 | 
				
			||||||
    platforms: await getInputList('platforms'),
 | 
					    platforms: await getInputList('platforms'),
 | 
				
			||||||
    provenance: core.getInput('provenance'),
 | 
					    provenance: getProvenanceInput('provenance'),
 | 
				
			||||||
    pull: core.getBooleanInput('pull'),
 | 
					    pull: core.getBooleanInput('pull'),
 | 
				
			||||||
    push: core.getBooleanInput('push'),
 | 
					    push: core.getBooleanInput('push'),
 | 
				
			||||||
    sbom: core.getInput('sbom'),
 | 
					    sbom: core.getInput('sbom'),
 | 
				
			||||||
| 
						 | 
					@ -162,9 +166,8 @@ async function getBuildArgs(inputs: Inputs, defaultContext: string, context: str
 | 
				
			||||||
    args.push('--platform', inputs.platforms.join(','));
 | 
					    args.push('--platform', inputs.platforms.join(','));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if (buildx.satisfies(buildxVersion, '>=0.10.0')) {
 | 
					  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) {
 | 
					    if (inputs.provenance) {
 | 
				
			||||||
      args.push('--provenance', getProvenanceAttrs(inputs.provenance, prvBuilderID));
 | 
					      args.push('--provenance', inputs.provenance);
 | 
				
			||||||
    } else if ((await buildx.satisfiesBuildKitVersion(inputs.builder, '>=0.11.0', standalone)) && !hasDockerExport(inputs)) {
 | 
					    } else if ((await buildx.satisfiesBuildKitVersion(inputs.builder, '>=0.11.0', standalone)) && !hasDockerExport(inputs)) {
 | 
				
			||||||
      // if provenance not specified and BuildKit version compatible for
 | 
					      // if provenance not specified and BuildKit version compatible for
 | 
				
			||||||
      // attestation, set default provenance. Also needs to make sure user
 | 
					      // attestation, set default provenance. Also needs to make sure user
 | 
				
			||||||
| 
						 | 
					@ -172,12 +175,10 @@ async function getBuildArgs(inputs: Inputs, defaultContext: string, context: str
 | 
				
			||||||
      if (fromPayload('repository.private') !== false) {
 | 
					      if (fromPayload('repository.private') !== false) {
 | 
				
			||||||
        // if this is a private repository, we set the default provenance
 | 
					        // 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
 | 
					        // attributes being set in buildx: https://github.com/docker/buildx/blob/fb27e3f919dcbf614d7126b10c2bc2d0b1927eb6/build/build.go#L603
 | 
				
			||||||
        // along the builder-id attribute.
 | 
					        args.push('--provenance', getProvenanceAttrs(`mode=min,inline-only=true`));
 | 
				
			||||||
        args.push('--provenance', `mode=min,inline-only=true,builder-id=${prvBuilderID}`);
 | 
					 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        // for a public repository, we set max provenance mode and the
 | 
					        // for a public repository, we set max provenance mode.
 | 
				
			||||||
        // builder-id attribute.
 | 
					        args.push('--provenance', getProvenanceAttrs(`mode=max`));
 | 
				
			||||||
        args.push('--provenance', `mode=max,builder-id=${prvBuilderID}`);
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (inputs.sbom) {
 | 
					    if (inputs.sbom) {
 | 
				
			||||||
| 
						 | 
					@ -298,7 +299,24 @@ function select(obj: any, path: string): any {
 | 
				
			||||||
  return select(obj[key], path.slice(i + 1));
 | 
					  return select(obj[key], path.slice(i + 1));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function getProvenanceAttrs(input: string, builderID: string): string {
 | 
					function getProvenanceInput(name: string): string {
 | 
				
			||||||
 | 
					  const input = core.getInput(name);
 | 
				
			||||||
 | 
					  if (!input) {
 | 
				
			||||||
 | 
					    // if input is not set, default values will be set later.
 | 
				
			||||||
 | 
					    return input;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  const builderID = provenanceBuilderID();
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					    return core.getBooleanInput(name) ? `builder-id=${builderID}` : 'false';
 | 
				
			||||||
 | 
					  } catch (err) {
 | 
				
			||||||
 | 
					    // not a valid boolean, so we assume it's a string
 | 
				
			||||||
 | 
					    return getProvenanceAttrs(input);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function getProvenanceAttrs(input: string): string {
 | 
				
			||||||
 | 
					  const builderID = provenanceBuilderID();
 | 
				
			||||||
 | 
					  // parse attributes from input
 | 
				
			||||||
  const fields = parse(input, {
 | 
					  const fields = parse(input, {
 | 
				
			||||||
    relaxColumnCount: true,
 | 
					    relaxColumnCount: true,
 | 
				
			||||||
    skipEmptyLines: true
 | 
					    skipEmptyLines: true
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue