Skip to content

Commit 6012983

Browse files
authored
GitHub actions (#55)
Switch to GitHub actions.
1 parent ad8e8d6 commit 6012983

22 files changed

+1087
-357
lines changed

.github/CODEOWNERS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
* @IronCoreLabs/js-dev
2+
/.github/ @IronCoreLabs/ops

.github/bump-version-patch.yaml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# If we're running on merge to main, then we're just incrementing the "-pre.N" and starting the docker workflow.
2+
# If we're running from workflow_dispatch, then we're making a new release.
3+
# The next several entries in the patch cover the two cases just described.
4+
- op: replace
5+
path: /on/workflow_dispatch
6+
value:
7+
inputs:
8+
version:
9+
description: New semver release version.
10+
required: true
11+
- op: replace
12+
path: /jobs/bump/steps/2
13+
value:
14+
name: Compute version
15+
id: versions
16+
run: |
17+
set -x
18+
# Read the current prerelease version.
19+
VERSION=$(.github/bump-version.sh)
20+
echo "::set-output name=old::${VERSION}"
21+
BUILDNUM=$(echo "${VERSION}" | sed 's/[^0-9][^0-9]*/ /g' | awk '{print $NF}')
22+
if [ "${BUILDNUM}" = "" ] ; then
23+
BUILDNUM=0
24+
fi
25+
26+
# Set the release version. If this is a workflow_dispatch, use the specified version. Otherwise increment the "-pre.N" part.
27+
if [ -n "${{ github.event.inputs.version }}" ] ; then
28+
VERSION="${{ github.event.inputs.version }}"
29+
else
30+
BUILDNUM=$(expr "${BUILDNUM}" + 1)
31+
VERSION="$(echo "${VERSION}" | sed 's/-.*//')"
32+
VERSION="${VERSION}-pre.${BUILDNUM}"
33+
fi
34+
echo "::set-output name=release::${VERSION}"
35+
36+
# Is it a release version? If so, it won't have a '-' character in it. "1.2.3-pre.4" is not a release version.
37+
if [[ ${VERSION} =~ .*-.* ]] ; then
38+
echo "::set-output name=is_release::false"
39+
else
40+
echo "::set-output name=is_release::true"
41+
VERSION="$(echo "${VERSION}" | awk -F. -v OFS=. '{$NF += 1 ; print}')-pre.1"
42+
echo "::set-output name=bumped::${VERSION}"
43+
fi
44+
- op: add
45+
path: /jobs/bump/steps/8/if
46+
value: ${{ steps.versions.outputs.bumped != '' }}
47+
- op: add
48+
path: /jobs/bump/steps/9/if
49+
value: ${{ steps.versions.outputs.bumped != '' }}

.github/bump-version.sh

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
#!/bin/bash
2+
3+
# Get or set the semver in various files.
4+
5+
# If called with no args, return the current version.
6+
# If called with one arg, set the version to the new value.
7+
8+
# Always performs sanity checking:
9+
# - There must be at least one version file.
10+
# - All version files must agree. (Ignoring the contents but not existence of pre-release version.)
11+
# - The version must be a valid semver.
12+
# - The version must not be 0.0.0.
13+
14+
# If setting the version to $a.$b.$c-$pre, substitute "SNAPSHOT" for $pre in any Java-related files.
15+
16+
set -e
17+
18+
# Parse args
19+
case "$#" in
20+
"0")
21+
NEWVERS=""
22+
;;
23+
"1")
24+
NEWVERS="$1"
25+
;;
26+
"*")
27+
echo "Usage: $0 [version]" 1>&2
28+
exit 1
29+
;;
30+
esac
31+
32+
# Find the version files in this directory or its descendants, but don't recurse too deep.
33+
VERSFILES=$(find . -maxdepth 3 ! -path ./.git/\* | grep -E '.*/(version|Cargo.toml|package.json|pom.xml|version.sbt)$')
34+
35+
# Do we have at least one?
36+
if [ -z "${VERSFILES}" ] ; then
37+
echo "No version files found; aborting" 1>&2
38+
exit 1
39+
fi
40+
41+
# Read the versions.
42+
CURRENTVERS=""
43+
for FILE in ${VERSFILES} ; do
44+
# Parse each version file according to its type.
45+
case $(basename "${FILE}") in
46+
version)
47+
# It's a file to capture version info for generic things that don't have their own format.
48+
VERS=$(cat "${FILE}")
49+
;;
50+
Cargo.toml)
51+
VERS=$(cargo metadata --manifest-path "${FILE}" --no-deps --offline --format-version 1 | jq -r '.packages[0].version')
52+
;;
53+
package.json)
54+
if [ "$(dirname "${FILE}")" = "." ] ; then
55+
# This is the root package.json, so we want .version.
56+
VERS=$(jq -r '.version' < "${FILE}")
57+
else
58+
# This isn't the root package.json, so we assume it depends on the package declared in the root package.json. We need to
59+
# get the root package's name.
60+
ROOTJSNAME=$(jq -r '.name' < package.json)
61+
VERS=$(jq -r ".dependencies[\"${ROOTJSNAME}\"]" < "${FILE}")
62+
# Strip off any leading "^".
63+
VERS=${VERS/^/}
64+
fi
65+
;;
66+
./pom.xml)
67+
if [ "$(dirname "${FILE}")" = "." ] ; then
68+
# This is the root pom.xml, so we want /m:project/m:version.
69+
VERS=$(xmlstarlet sel -N m="http://maven.apache.org/POM/4.0.0" -t -v "/m:project/m:version" < "${FILE}")
70+
else
71+
# This isn't the root pom.xml, so we assume it depends on the package declared in the root pom.xml. We need to get the
72+
# root pom's artifactId.
73+
ROOTID=$(xmlstarlet sel -N m="http://maven.apache.org/POM/4.0.0" -t -v "/m:project/m:artifactId" < pom.xml)
74+
# Select /m:project/m:dependencies/m:dependency/m:version where it has a sibling m:artifactId with the correct value.
75+
XPATH="/m:project/m:dependencies/m:dependency[m:artifactId=\"${ROOTID}\"]/m:version"
76+
VERS=$(xmlstarlet sel -N m="http://maven.apache.org/POM/4.0.0" -t -v "${XPATH}" < "${FILE}")
77+
fi
78+
;;
79+
version.sbt)
80+
VERS=$(sed -e 's/^[^"]*"//' -e 's/"$//' < "${FILE}")
81+
;;
82+
*)
83+
echo "Can't parse '${FILE}' for version" 1>&2
84+
exit 1
85+
;;
86+
esac
87+
88+
if [ -z "${VERS}" ] ; then
89+
echo "Empty version from '${FILE}'" 1>&2
90+
exit 1
91+
fi
92+
93+
# If this is the first parsed version file, then set current version.
94+
if [ -z "${CURRENTVERS}" ] ; then
95+
CURRENTVERS="${VERS}"
96+
fi
97+
98+
# Compare this file's version to other files' version. Ignore anything after the "-" in a pre-release version, but keep the "-"
99+
# so a release version is unequal to a pre-release.
100+
if ! [ "${CURRENTVERS/-*/-}" = "${VERS/-*/-}" ] ; then
101+
echo "Version '${VERS}' in '${FILE}' doesn't match '${CURRENTVERS}' from others in '${VERSFILES}'" 1>&2
102+
exit 1
103+
fi
104+
done
105+
106+
# Sanity check: Ignoring any pre-release info, version must not be 0.0.0.
107+
if [ "${CURRENTVERS/-*/}" = "0.0.0" ] ; then
108+
echo "Illegal zero version '${CURRENTVERS}'" 1>&2
109+
exit 1
110+
fi
111+
# Sanity check: Must be valid semver.
112+
if ! [[ ${CURRENTVERS} =~ ^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-((0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*))?(\+([0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*))?$ ]] ; then
113+
echo "Invalid version '${CURRENTVERS}'" 1>&2
114+
exit 1
115+
fi
116+
117+
# If we're just getting the current version, print it and exit successfully.
118+
if [ -z "${NEWVERS}" ] ; then
119+
echo "${CURRENTVERS}"
120+
exit 0
121+
fi
122+
123+
# If we reach this point, it means we're setting the version.
124+
125+
# Edit the version files.
126+
for FILE in ${VERSFILES} ; do
127+
DIR=$(dirname "${FILE}")
128+
case $(basename "${FILE}") in
129+
version)
130+
echo "${NEWVERS}" > "${FILE}"
131+
;;
132+
133+
Cargo.toml)
134+
sed -i 's/^version = ".*"$/version = "'"${NEWVERS}"'"/' "${FILE}"
135+
136+
# If there's a Cargo.lock, update it also.
137+
if [ -f "${DIR}/Cargo.lock" ] ; then
138+
( cd "${DIR}" && cargo fetch )
139+
git add "${DIR}/Cargo.lock"
140+
fi
141+
;;
142+
143+
package.json)
144+
if [ "$(dirname "${FILE}")" = "." ] ; then
145+
# This is the root package.json, so we want .version.
146+
jq --indent 4 ".version=\"${NEWVERS}\"" "${FILE}" > "${FILE}.new"
147+
else
148+
# We already know the root package name from above, so reuse that here.
149+
jq --indent 4 ".dependencies[\"${ROOTJSNAME}\"]=\"^${NEWVERS}\"" "${FILE}" > "${FILE}.new"
150+
fi
151+
mv "${FILE}.new" "${FILE}"
152+
;;
153+
154+
pom.xml)
155+
# Replace -foo with -SNAPSHOT to be compatible with Java conventions.
156+
JAVAVERS="${NEWVERS/-*/-SNAPSHOT}"
157+
158+
if [ "$(dirname "${FILE}")" = "." ] ; then
159+
# This is the root pom.xml, so we want /m:project/m:version.
160+
xmlstarlet ed -L -P -N m="http://maven.apache.org/POM/4.0.0" -u "/m:project/m:version" -v "${JAVAVERS}" "${FILE}"
161+
else
162+
# We've already computed our XPATH expression above, so reuse that here.
163+
xmlstarlet ed -L -P -N m="http://maven.apache.org/POM/4.0.0" -u "${XPATH}" -v "${JAVAVERS}" "${FILE}"
164+
fi
165+
;;
166+
167+
version.sbt)
168+
# Replace -foo with -SNAPSHOT to be compatible with Java conventions.
169+
JAVAVERS="${NEWVERS/-*/-SNAPSHOT}"
170+
171+
# The file might use the old, deprecated syntax or the newer syntax:
172+
# version in ThisBuild := "1.2.3-SNAPSHOT"
173+
# ThisBuild / version := "1.2.3-SNAPSHOT"
174+
sed -i 's,^ThisBuild / version := ".*"$,ThisBuild / version := "'"${JAVAVERS}"'",' "${FILE}"
175+
sed -i 's,^version in ThisBuild := ".*"$,ThisBuild / version := "'"${JAVAVERS}"'",' "${FILE}"
176+
;;
177+
178+
*)
179+
echo "Can't edit '${FILE}' with new version" 1>&2
180+
exit 1
181+
esac
182+
183+
# Add it to git.
184+
git add "${FILE}"
185+
# Verify that we've changed zero or one line.
186+
git diff --cached -w --numstat "${FILE}" > /tmp/diffcount
187+
if [ -s /tmp/diffcount ] ; then
188+
# shellcheck disable=SC2034
189+
read -r ADDED REMOVED FILENAME < /tmp/diffcount
190+
if [ "${ADDED}" -ne 1 ] || [ "${REMOVED}" -ne 1 ] ; then
191+
echo "Changes to '${FILE}' must be zero or one line, but observed edits are:" 1>&2
192+
git diff --cached "${FILE}" 1>&2
193+
exit 1
194+
fi
195+
fi
196+
done
197+
198+
# Look for files that have been changed, but that we haven't told git about.
199+
echo "Checking for modified but untracked files:"
200+
if git status -s | grep -qEv '^M ' ; then
201+
echo "Modified but untracked files:" 1>&2
202+
git status -s | grep -Ev '^M ' 1>&2
203+
echo "This probably means '$0' modified a file but forgot to 'git add' it." 1>&2
204+
exit 1
205+
fi

.github/rust-ci-patch.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Tests are run from the Typescript side, not here.
2+
- op: remove
3+
path: /jobs/cargo-test
4+
- op: remove
5+
path: /jobs/coverage
6+
7+
# Everything needs to run in the native directory.
8+
- op: add
9+
path: /defaults
10+
value:
11+
run:
12+
working-directory: native

.github/rust-daily-patch.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Everything needs to run in the native directory.
2+
- op: add
3+
path: /defaults
4+
value:
5+
run:
6+
working-directory: native

.github/typescript-ci-patch.yaml

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Run tests on different versions of node and rust, and on different OSes.
2+
- op: replace
3+
path: /jobs/test/strategy/matrix
4+
value:
5+
node_version:
6+
- "10"
7+
- "12"
8+
- "14"
9+
rust_version:
10+
- 1.48.0
11+
- stable
12+
- beta
13+
os:
14+
- macos-10.15
15+
- ubuntu-20.04
16+
- windows-2019
17+
- op: add
18+
path: /jobs/test/strategy/fail-fast
19+
value: false
20+
- op: replace
21+
path: /jobs/test/runs-on
22+
value: "${{ matrix.os }}"
23+
24+
# These steps are lifted from the Rust CI workflow, cargo-test job.
25+
- op: add
26+
path: /jobs/test/steps/3
27+
value:
28+
uses: actions-rs/toolchain@v1
29+
with:
30+
profile: minimal
31+
toolchain: ${{ matrix.rust_version }}
32+
override: true
33+
34+
# Modify the yarn actions.
35+
- op: replace
36+
path: /jobs/test/steps/4/run
37+
value: yarn install --ignore-scripts
38+
- op: add
39+
path: /jobs/test/steps/5
40+
value:
41+
name: Compile
42+
run: yarn run compile
43+
44+
# Only check coverage in one of the matrix job instances.
45+
- op: add
46+
path: /jobs/test/steps/7/if
47+
value: ${{ contains(matrix.os, 'ubuntu') && matrix.node_version == '10' && matrix.rust_version == 'stable' }}
48+
49+
# Also run on musl. That means we need to run it in a Docker container. To do that, we copy the entire job and modify its
50+
# strategy/matrix.
51+
- op: copy
52+
from: /jobs/test
53+
path: /jobs/test-docker
54+
- op: replace
55+
path: /jobs/test-docker/strategy/matrix/os
56+
value:
57+
- ubuntu-18.04
58+
- op: add
59+
path: /jobs/test-docker/container
60+
value:
61+
image: node:${{ matrix.node_version }}-alpine
62+
# Set up some tools in the container that our other actions depend on.
63+
- op: add
64+
path: /jobs/test-docker/steps/0
65+
value:
66+
run: apk add build-base git python3 wget
67+
# hack to get dynlibs working with musl
68+
# https://github.com/rust-lang/rust/pull/55163#issuecomment-436631090
69+
- op: add
70+
path: /jobs/test-docker/steps/1
71+
value:
72+
run: echo RUSTFLAGS="-C target-feature=-crt-static" >> "${GITHUB_ENV}"
73+
# We don't need to run setup-node inside of a node docker image.
74+
- op: remove
75+
path: /jobs/test-docker/steps/4

0 commit comments

Comments
 (0)