Skip to content

Commit 3d63b9d

Browse files
committed
Update CI & CD
1 parent d7bacf0 commit 3d63b9d

File tree

3 files changed

+372
-401
lines changed

3 files changed

+372
-401
lines changed

.github/workflows/CICD.yaml

+372
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,372 @@
1+
name: CICD
2+
3+
env:
4+
MIN_SUPPORTED_RUST_VERSION: "1.45.0"
5+
CICD_INTERMEDIATES_DIR: "_cicd-intermediates"
6+
7+
on:
8+
workflow_dispatch:
9+
pull_request:
10+
push:
11+
branches:
12+
- master
13+
tags:
14+
- '*'
15+
16+
jobs:
17+
min_version:
18+
name: Minimum supported rust version
19+
runs-on: ubuntu-20.04
20+
steps:
21+
- name: Checkout source code
22+
uses: actions/checkout@v2
23+
24+
- name: Install rust toolchain (v${{ env.MIN_SUPPORTED_RUST_VERSION }})
25+
uses: actions-rs/toolchain@v1
26+
with:
27+
toolchain: ${{ env.MIN_SUPPORTED_RUST_VERSION }}
28+
default: true
29+
profile: minimal # minimal component installation (ie, no documentation)
30+
components: clippy, rustfmt
31+
- name: Ensure `cargo fmt` has been run
32+
uses: actions-rs/cargo@v1
33+
with:
34+
command: fmt
35+
args: -- --check
36+
- name: Run clippy (on minimum supported rust version to prevent warnings we can't fix)
37+
uses: actions-rs/cargo@v1
38+
with:
39+
command: clippy
40+
args: --locked --all-targets --all-features
41+
- name: Run tests
42+
uses: actions-rs/cargo@v1
43+
with:
44+
command: test
45+
args: --locked
46+
47+
test_with_new_syntaxes_and_themes:
48+
name: Run tests with updated syntaxes and themes
49+
runs-on: ubuntu-20.04
50+
steps:
51+
- name: Git checkout
52+
uses: actions/checkout@v2
53+
with:
54+
submodules: true # we need all syntax and theme submodules
55+
- name: Install Rust toolchain
56+
uses: actions-rs/toolchain@v1
57+
with:
58+
toolchain: stable
59+
default: true
60+
profile: minimal
61+
- name: Build and install rustpython
62+
uses: actions-rs/cargo@v1
63+
with:
64+
command: install
65+
args: --locked --path .
66+
- name: Rebuild binary assets (syntaxes and themes)
67+
run: bash assets/create.sh
68+
- name: Build and install rustpython with updated assets
69+
uses: actions-rs/cargo@v1
70+
with:
71+
command: install
72+
args: --locked --path .
73+
- name: Run unit tests with new syntaxes and themes
74+
uses: actions-rs/cargo@v1
75+
with:
76+
command: test
77+
args: --locked --release
78+
- name: Run ignored-by-default unit tests with new syntaxes and themes
79+
uses: actions-rs/cargo@v1
80+
with:
81+
command: test
82+
args: --locked --release -- --ignored
83+
- name: Syntax highlighting regression test
84+
run: tests/syntax-tests/regression_test.sh
85+
- name: List of languages
86+
run: rustpython --list-languages
87+
- name: List of themes
88+
run: rustpython --list-themes
89+
- name: Check documentation
90+
env:
91+
RUSTDOCFLAGS: -D warnings
92+
uses: actions-rs/cargo@v1
93+
with:
94+
command: doc
95+
args: --locked --no-deps --document-private-items --all-features
96+
97+
build:
98+
name: ${{ matrix.job.os }} (${{ matrix.job.target }})
99+
runs-on: ${{ matrix.job.os }}
100+
strategy:
101+
fail-fast: false
102+
matrix:
103+
job:
104+
- { os: ubuntu-20.04, target: arm-unknown-linux-gnueabihf , use-cross: true }
105+
- { os: ubuntu-20.04, target: arm-unknown-linux-musleabihf, use-cross: true }
106+
- { os: ubuntu-20.04, target: aarch64-unknown-linux-gnu , use-cross: true }
107+
- { os: ubuntu-20.04, target: i686-unknown-linux-gnu , use-cross: true }
108+
- { os: ubuntu-20.04, target: i686-unknown-linux-musl , use-cross: true }
109+
- { os: ubuntu-20.04, target: x86_64-unknown-linux-gnu }
110+
- { os: ubuntu-20.04, target: x86_64-unknown-linux-musl , use-cross: true }
111+
- { os: macos-10.15 , target: x86_64-apple-darwin }
112+
# - { os: windows-2019, target: i686-pc-windows-gnu } ## disabled; error: linker `i686-w64-mingw32-gcc` not found
113+
- { os: windows-2019, target: i686-pc-windows-msvc }
114+
- { os: windows-2019, target: x86_64-pc-windows-gnu }
115+
- { os: windows-2019, target: x86_64-pc-windows-msvc }
116+
steps:
117+
- name: Checkout source code
118+
uses: actions/checkout@v2
119+
120+
- name: Install prerequisites
121+
shell: bash
122+
run: |
123+
case ${{ matrix.job.target }} in
124+
arm-unknown-linux-*) sudo apt-get -y update ; sudo apt-get -y install gcc-arm-linux-gnueabihf ;;
125+
aarch64-unknown-linux-gnu) sudo apt-get -y update ; sudo apt-get -y install gcc-aarch64-linux-gnu ;;
126+
esac
127+
128+
- name: Extract crate information
129+
shell: bash
130+
run: |
131+
echo "PROJECT_NAME=$(sed -n 's/^name = "\(.*\)"/\1/p' Cargo.toml | head -n1)" >> $GITHUB_ENV
132+
echo "PROJECT_VERSION=$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -n1)" >> $GITHUB_ENV
133+
echo "PROJECT_MAINTAINER=$(sed -n 's/^authors = \["\(.*\)"\]/\1/p' Cargo.toml)" >> $GITHUB_ENV
134+
echo "PROJECT_HOMEPAGE=$(sed -n 's/^homepage = "\(.*\)"/\1/p' Cargo.toml)" >> $GITHUB_ENV
135+
136+
- name: Install Rust toolchain
137+
uses: actions-rs/toolchain@v1
138+
with:
139+
toolchain: stable
140+
target: ${{ matrix.job.target }}
141+
override: true
142+
profile: minimal # minimal component installation (ie, no documentation)
143+
144+
- name: Show version information (Rust, cargo, GCC)
145+
shell: bash
146+
run: |
147+
gcc --version || true
148+
rustup -V
149+
rustup toolchain list
150+
rustup default
151+
cargo -V
152+
rustc -V
153+
154+
- name: Build
155+
uses: actions-rs/cargo@v1
156+
with:
157+
use-cross: ${{ matrix.job.use-cross }}
158+
command: build
159+
args: --locked --release --target=${{ matrix.job.target }}
160+
161+
- name: Strip debug information from executable
162+
id: strip
163+
shell: bash
164+
run: |
165+
# Figure out suffix of binary
166+
EXE_suffix=""
167+
case ${{ matrix.job.target }} in
168+
*-pc-windows-*) EXE_suffix=".exe" ;;
169+
esac;
170+
171+
# Figure out what strip tool to use if any
172+
STRIP="strip"
173+
case ${{ matrix.job.target }} in
174+
arm-unknown-linux-*) STRIP="arm-linux-gnueabihf-strip" ;;
175+
aarch64-unknown-linux-gnu) STRIP="aarch64-linux-gnu-strip" ;;
176+
*-pc-windows-msvc) STRIP="" ;;
177+
esac;
178+
179+
# Setup paths
180+
BIN_DIR="${{ env.CICD_INTERMEDIATES_DIR }}/stripped-release-bin/"
181+
mkdir -p "${BIN_DIR}"
182+
BIN_NAME="${{ env.PROJECT_NAME }}${EXE_suffix}"
183+
BIN_PATH="${BIN_DIR}/${BIN_NAME}"
184+
185+
# Copy the release build binary to the result location
186+
cp "target/${{ matrix.job.target }}/release/${BIN_NAME}" "${BIN_DIR}"
187+
188+
# Also strip if possible
189+
if [ -n "${STRIP}" ]; then
190+
"${STRIP}" "${BIN_PATH}"
191+
fi
192+
193+
# Let subsequent steps know where to find the (stripped) bin
194+
echo ::set-output name=BIN_PATH::${BIN_PATH}
195+
echo ::set-output name=BIN_NAME::${BIN_NAME}
196+
197+
- name: Create tarball
198+
id: package
199+
shell: bash
200+
run: |
201+
PKG_suffix=".tar.gz" ; case ${{ matrix.job.target }} in *-pc-windows-*) PKG_suffix=".zip" ;; esac;
202+
PKG_BASENAME=${PROJECT_NAME}-v${PROJECT_VERSION}-${{ matrix.job.target }}
203+
PKG_NAME=${PKG_BASENAME}${PKG_suffix}
204+
echo ::set-output name=PKG_NAME::${PKG_NAME}
205+
206+
PKG_STAGING="${{ env.CICD_INTERMEDIATES_DIR }}/package"
207+
ARCHIVE_DIR="${PKG_STAGING}/${PKG_BASENAME}/"
208+
mkdir -p "${ARCHIVE_DIR}"
209+
mkdir -p "${ARCHIVE_DIR}/autocomplete"
210+
211+
# Binary
212+
cp "${{ steps.strip.outputs.BIN_PATH }}" "$ARCHIVE_DIR"
213+
214+
# Man page
215+
cp 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/manual/rustpython.1 "$ARCHIVE_DIR"
216+
217+
# README, LICENSE and CHANGELOG files
218+
cp "README.md" "LICENSE-MIT" "LICENSE-APACHE" "CHANGELOG.md" "$ARCHIVE_DIR"
219+
220+
# Autocompletion files
221+
cp 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/rustpython.bash "$ARCHIVE_DIR/autocomplete/${{ env.PROJECT_NAME }}.bash"
222+
cp 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/rustpython.fish "$ARCHIVE_DIR/autocomplete/${{ env.PROJECT_NAME }}.fish"
223+
cp 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/rustpython.zsh "$ARCHIVE_DIR/autocomplete/${{ env.PROJECT_NAME }}.zsh"
224+
225+
# base compressed package
226+
pushd "${PKG_STAGING}/" >/dev/null
227+
case ${{ matrix.job.target }} in
228+
*-pc-windows-*) 7z -y a "${PKG_NAME}" "${PKG_BASENAME}"/* | tail -2 ;;
229+
*) tar czf "${PKG_NAME}" "${PKG_BASENAME}"/* ;;
230+
esac;
231+
popd >/dev/null
232+
233+
# Let subsequent steps know where to find the compressed package
234+
echo ::set-output name=PKG_PATH::"${PKG_STAGING}/${PKG_NAME}"
235+
236+
- name: Create Debian package
237+
id: debian-package
238+
shell: bash
239+
if: startsWith(matrix.job.os, 'ubuntu')
240+
run: |
241+
COPYRIGHT_YEARS="2018 - "$(date "+%Y")
242+
DPKG_STAGING="${{ env.CICD_INTERMEDIATES_DIR }}/debian-package"
243+
DPKG_DIR="${DPKG_STAGING}/dpkg"
244+
mkdir -p "${DPKG_DIR}"
245+
246+
DPKG_BASENAME=${PROJECT_NAME}
247+
DPKG_CONFLICTS=${PROJECT_NAME}-musl
248+
case ${{ matrix.job.target }} in *-musl) DPKG_BASENAME=${PROJECT_NAME}-musl ; DPKG_CONFLICTS=${PROJECT_NAME} ;; esac;
249+
DPKG_VERSION=${PROJECT_VERSION}
250+
251+
unset DPKG_ARCH
252+
case ${{ matrix.job.target }} in
253+
aarch64-*-linux-*) DPKG_ARCH=arm64 ;;
254+
arm-*-linux-*hf) DPKG_ARCH=armhf ;;
255+
i686-*-linux-*) DPKG_ARCH=i686 ;;
256+
x86_64-*-linux-*) DPKG_ARCH=amd64 ;;
257+
*) DPKG_ARCH=notset ;;
258+
esac;
259+
260+
DPKG_NAME="${DPKG_BASENAME}_${DPKG_VERSION}_${DPKG_ARCH}.deb"
261+
echo ::set-output name=DPKG_NAME::${DPKG_NAME}
262+
263+
# Binary
264+
install -Dm755 "${{ steps.strip.outputs.BIN_PATH }}" "${DPKG_DIR}/usr/bin/${{ steps.strip.outputs.BIN_NAME }}"
265+
266+
# Man page
267+
install -Dm644 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/manual/rustpython.1 "${DPKG_DIR}/usr/share/man/man1/${{ env.PROJECT_NAME }}.1"
268+
gzip -n --best "${DPKG_DIR}/usr/share/man/man1/${{ env.PROJECT_NAME }}.1"
269+
270+
# Autocompletion files
271+
install -Dm644 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/rustpython.fish "${DPKG_DIR}/usr/share/fish/vendor_completions.d/${{ env.PROJECT_NAME }}.fish"
272+
install -Dm644 'target/${{ matrix.job.target }}/release/build/${{ env.PROJECT_NAME }}'-*/out/assets/completions/rustpython.zsh "${DPKG_DIR}/usr/share/zsh/vendor-completions/_${{ env.PROJECT_NAME }}"
273+
274+
# README and LICENSE
275+
install -Dm644 "README.md" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/README.md"
276+
install -Dm644 "LICENSE-MIT" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/LICENSE-MIT"
277+
install -Dm644 "LICENSE-APACHE" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/LICENSE-APACHE"
278+
install -Dm644 "CHANGELOG.md" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/changelog"
279+
gzip -n --best "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/changelog"
280+
281+
cat > "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/copyright" <<EOF
282+
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
283+
Upstream-Name: ${{ env.PROJECT_NAME }}
284+
Source: ${{ env.PROJECT_HOMEPAGE }}
285+
286+
Files: *
287+
Copyright: ${{ env.PROJECT_MAINTAINER }}
288+
Copyright: $COPYRIGHT_YEARS ${{ env.PROJECT_MAINTAINER }}
289+
License: Apache-2.0 or MIT
290+
291+
License: Apache-2.0
292+
On Debian systems, the complete text of the Apache-2.0 can be found in the
293+
file /usr/share/common-licenses/Apache-2.0.
294+
295+
License: MIT
296+
Permission is hereby granted, free of charge, to any
297+
person obtaining a copy of this software and associated
298+
documentation files (the "Software"), to deal in the
299+
Software without restriction, including without
300+
limitation the rights to use, copy, modify, merge,
301+
publish, distribute, sublicense, and/or sell copies of
302+
the Software, and to permit persons to whom the Software
303+
is furnished to do so, subject to the following
304+
conditions:
305+
.
306+
The above copyright notice and this permission notice
307+
shall be included in all copies or substantial portions
308+
of the Software.
309+
.
310+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
311+
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
312+
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
313+
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
314+
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
315+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
316+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
317+
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
318+
DEALINGS IN THE SOFTWARE.
319+
EOF
320+
chmod 644 "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/copyright"
321+
322+
# control file
323+
mkdir -p "${DPKG_DIR}/DEBIAN"
324+
cat > "${DPKG_DIR}/DEBIAN/control" <<EOF
325+
Package: ${DPKG_BASENAME}
326+
Version: ${DPKG_VERSION}
327+
Section: utils
328+
Priority: optional
329+
Maintainer: ${{ env.PROJECT_MAINTAINER }}
330+
Homepage: ${{ env.PROJECT_HOMEPAGE }}
331+
Architecture: ${DPKG_ARCH}
332+
Provides: ${{ env.PROJECT_NAME }}
333+
Conflicts: ${DPKG_CONFLICTS}
334+
Description: cat(1) clone with wings.
335+
A cat(1) clone with syntax highlighting and Git integration.
336+
EOF
337+
338+
DPKG_PATH="${DPKG_STAGING}/${DPKG_NAME}"
339+
echo ::set-output name=DPKG_PATH::${DPKG_PATH}
340+
341+
# build dpkg
342+
fakeroot dpkg-deb --build "${DPKG_DIR}" "${DPKG_PATH}"
343+
344+
- name: "Artifact upload: tarball"
345+
uses: actions/upload-artifact@master
346+
with:
347+
name: ${{ steps.package.outputs.PKG_NAME }}
348+
path: ${{ steps.package.outputs.PKG_PATH }}
349+
350+
- name: "Artifact upload: Debian package"
351+
uses: actions/upload-artifact@master
352+
if: steps.debian-package.outputs.DPKG_NAME
353+
with:
354+
name: ${{ steps.debian-package.outputs.DPKG_NAME }}
355+
path: ${{ steps.debian-package.outputs.DPKG_PATH }}
356+
357+
- name: Check for release
358+
id: is-release
359+
shell: bash
360+
run: |
361+
unset IS_RELEASE ; if [[ $GITHUB_REF =~ ^refs/tags/v[0-9].* ]]; then IS_RELEASE='true' ; fi
362+
echo ::set-output name=IS_RELEASE::${IS_RELEASE}
363+
364+
- name: Publish archives and packages
365+
uses: softprops/action-gh-release@v1
366+
if: steps.is-release.outputs.IS_RELEASE
367+
with:
368+
files: |
369+
${{ steps.package.outputs.PKG_PATH }}
370+
${{ steps.debian-package.outputs.DPKG_PATH }}
371+
env:
372+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)