-
Notifications
You must be signed in to change notification settings - Fork 138
/
Copy pathgenerate-layout.sh
executable file
·96 lines (88 loc) · 3.23 KB
/
generate-layout.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#!/bin/bash -eu
#
# Copyright 2023 SLSA Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
# We will encode the subject name as an npm package url (purl).
# https://github.com/package-url/purl-spec/blob/master/PURL-SPECIFICATION.rst
#
# The npm package's scope is considered a purl "namespace" and not part of the
# package name. So the subject will take the form of:
#
# With scope:
# pkg:npm/<scope>/<name>@<version>
#
# Without scope:
# pkg:npm/<name>@<version>
#
# Each of scope, name, and version are URL(percent) encoded.
# Get the raw package name and scope from the output of `npm pack --json`
# This name is of the form '<scope>/<package name>'
raw_package_scope=$(echo "${PACKAGE_NAME:-}" | cut -d'/' -f1)
raw_package_name=$(echo "${PACKAGE_NAME:-}" | cut -d'/' -f2)
if [ "${raw_package_name}" == "" ]; then
raw_package_name="${raw_package_scope}"
raw_package_scope=""
fi
# package scope (namespace) is URL(percent) encoded.
package_scope=$(echo "\"${raw_package_scope}\"" | jq -r '. | @uri')
# package name is URL(percent) encoded.
package_name=$(echo "\"${raw_package_name}\"" | jq -r '. | @uri')
# version is URL(percent) encoded. This is the version from the project's
# package.json and could be a commit, or any string by the user. It does not
# actually have to be a version number and is not validated as such by npm.
package_version=$(echo "\"${PACKAGE_VERSION:-}\"" | jq -r '. | @uri')
package_id="${package_name}@${package_version}"
if [ "${package_scope}" != "" ]; then
package_id="${package_scope}/${package_id}"
fi
subject_name="pkg:npm/${package_id}"
# The integrity digest is formatted as follows:
#
# <hash alg>-<base64 encoded checksum>
#
# For example:
# sha512-geEornsf879/Ygi9byQq/mpYboMcIKiGUxJ+RgHM3DCxqnOx15ttF5FparP/ZSITHTLM39MWVhW9qPa4XxtuSg==
integrity_digest="${PACKAGE_INTEGRITY:-}"
# We will parse out the checksum hash algorithm used.
# NOTE: ensure lowercase just to make sure.
alg=$(echo "${integrity_digest}" | cut -d'-' -f1 | tr '[:upper:]' '[:lower:]')
# Here we parse out the checksum and convert it from base64 to hex. 'od' seems
# to be the standard tool to do this kind conversion on Linux.
digest=$(echo "${integrity_digest}" | cut -d'-' -f2- | base64 -d | od -A n -v -t x1 | tr -d ' \n')
# NOTE: the name of the attestation should be configurable.
filename=${PACKAGE_FILENAME:-}
attestation_name="${filename%.*}"
cat <<EOF | jq | tee "${SLSA_OUTPUTS_ARTIFACTS_FILE}"
{
"version": 1,
"attestations":
[
{
"name": "${attestation_name}",
"subjects":
[
{
"name": "${subject_name}",
"digest":
{
"${alg}": "${digest}"
}
}
]
}
]
}
EOF
echo "attestation-name=${attestation_name}.build.slsa" >>"${GITHUB_OUTPUT}"