Skip to content

Commit a803574

Browse files
committed
0 parents  commit a803574

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+2041
-0
lines changed

.editorconfig

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
root = true
2+
3+
[*.cr]
4+
charset = utf-8
5+
end_of_line = lf
6+
insert_final_newline = true
7+
indent_style = space
8+
indent_size = 2
9+
trim_trailing_whitespace = true

.github/workflows/ci.yml

+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
pull_request:
6+
branches:
7+
- 'master'
8+
9+
jobs:
10+
prepare:
11+
name: Prepare
12+
runs-on: ubuntu-latest
13+
outputs:
14+
trusted: ${{ steps.contains_tag.outputs.retval }}
15+
matrix_json: ${{ steps.crystal_action.outputs.matrix_json }}
16+
crystal_version: ${{ steps.crystal_action.outputs.crystal_version }}
17+
steps:
18+
- name: Checkout
19+
uses: actions/checkout@v3
20+
with:
21+
fetch-depth: 0
22+
23+
- name: Lint
24+
uses: crystal-ameba/[email protected]
25+
env:
26+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
27+
28+
- name: Determine if tag is on trusted branch
29+
uses: rickstaa/action-contains-tag@0f592a0dd54a67d9af4545f6b6687ee01853d9a7
30+
id: contains_tag
31+
with:
32+
frail: false
33+
reference: "master"
34+
tag: "${{ github.ref }}"
35+
36+
- name: Crystal Action
37+
id: crystal_action
38+
run: .github/workflows/crystal_action.rb
39+
40+
build:
41+
name: Test & Build
42+
needs: prepare
43+
strategy:
44+
fail-fast: true
45+
matrix:
46+
include: ${{ fromJson(needs.prepare.outputs.matrix_json) }}
47+
runs-on: ${{ matrix.platform }}
48+
permissions:
49+
contents: write
50+
51+
steps:
52+
- name: Checkout
53+
uses: actions/checkout@v3
54+
55+
- if: matrix.platform != 'ubuntu-latest' && !endsWith(matrix.platform, '-arm')
56+
name: Install Crystal
57+
uses: crystal-lang/install-crystal@v1
58+
with:
59+
crystal: ${{ matrix.crystal }}
60+
61+
- if: matrix.platform != 'ubuntu-latest' && !endsWith(matrix.platform, '-arm')
62+
name: Test & Build (on runner host)
63+
run: |
64+
make clean ci release
65+
66+
- if: matrix.platform == 'ubuntu-latest' || endsWith(matrix.platform, '-arm')
67+
name: Test & Build (in alpine)
68+
uses: addnab/docker-run-action@v3
69+
with:
70+
image: 84codes/crystal:${{ matrix.crystal }}-alpine
71+
options: -v ${{ github.workspace }}:/workspace
72+
run: |
73+
cd /workspace && make clean ci release
74+
75+
- if: startsWith(github.ref, 'refs/tags/') && matrix.crystal == needs.prepare.outputs.crystal_version && needs.prepare.outputs.trusted == 'true'
76+
name: Compute checksum
77+
run: |
78+
shasum -a 256 build/* >checksums.txt
79+
80+
- if: startsWith(github.ref, 'refs/tags/') && matrix.crystal == needs.prepare.outputs.crystal_version && needs.prepare.outputs.trusted == 'true'
81+
name: Upload artifacts
82+
uses: actions/upload-artifact@v3
83+
with:
84+
name: sha256-${{ matrix.platform }}
85+
path: checksums.txt
86+
87+
- if: startsWith(github.ref, 'refs/tags/') && matrix.crystal == needs.prepare.outputs.crystal_version && needs.prepare.outputs.trusted == 'true'
88+
name: Draft release
89+
uses: ncipollo/release-action@v1
90+
with:
91+
artifacts: "build/*"
92+
allowUpdates: true
93+
draft: true
94+
updateOnlyUnreleased: false
95+
generateReleaseNotes: false
96+
omitBody: true
97+
98+
release:
99+
name: Release
100+
needs: [prepare, build]
101+
permissions:
102+
contents: write
103+
runs-on: ubuntu-latest
104+
105+
if: startsWith(github.ref, 'refs/tags/') && needs.prepare.outputs.trusted == 'true'
106+
steps:
107+
- name: Checkout
108+
uses: actions/checkout@v3
109+
110+
- name: Download artifacts
111+
uses: actions/download-artifact@v3
112+
113+
- name: Generate Release Notes
114+
run: .github/workflows/release_notes.sh >release.txt
115+
116+
- name: Finish Release
117+
uses: ncipollo/release-action@v1
118+
with:
119+
allowUpdates: true
120+
draft: false
121+
updateOnlyUnreleased: false
122+
generateReleaseNotes: false
123+
bodyFile: release.txt
124+
omitBody: false
125+

.github/workflows/crystal_action.rb

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/usr/bin/env ruby
2+
3+
# crystal_action.rb v1.0.0
4+
# (c)2023 [email protected] - MIT License
5+
6+
require 'json'
7+
require 'yaml'
8+
9+
SHARD_YML = YAML.load_file('shard.yml')
10+
11+
ENTRIES={}
12+
ENTRIES['platform'] = SHARD_YML['support_matrix']['platforms']
13+
ENTRIES['crystal'] = SHARD_YML['support_matrix']['crystal_versions'] # + %w[latest]
14+
15+
def product_hash(hsh)
16+
keys = hsh.keys
17+
attrs = keys.map { |key| hsh[key] }
18+
product = attrs[0].product(*attrs[1..-1])
19+
product.map{ |p| Hash[keys.zip p] }
20+
end
21+
22+
print "::set-output name=matrix_json::"
23+
puts product_hash(ENTRIES).to_json
24+
25+
print "::set-output name=crystal_version::"
26+
puts SHARD_YML['crystal']

.github/workflows/release_notes.sh

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
VERSION=$(git describe --tags | cut -c 2-)
6+
7+
cat <<EOF
8+
# Installation
9+
10+
## OSX
11+
12+
\`\`\`bash
13+
wget https://github.com/busyloop/envcat/releases/download/v${VERSION}/envcat-${VERSION}.darwin-x86_64
14+
sudo chmod +x envcat-${VERSION}.darwin-x86_64
15+
sudo mv envcat-${VERSION}.darwin-x86_64 /usr/bin
16+
sudo ln -sf /usr/bin/envcat-${VERSION}.darwin-x86_64 /usr/bin/envcat
17+
\`\`\`
18+
19+
## Linux
20+
21+
\`\`\`bash
22+
wget https://github.com/busyloop/envcat/releases/download/v${VERSION}/envcat-${VERSION}.linux-x86_64
23+
sudo chmod +x envcat-${VERSION}.linux-x86_64
24+
sudo mv envcat-${VERSION}.linux-x86_64 /usr/bin
25+
sudo ln -sf /usr/bin/envcat-${VERSION}.linux-x86_64 /usr/bin/envcat
26+
\`\`\`
27+
28+
29+
## Dockerfile :whale:
30+
31+
EOF
32+
33+
for ARCH in linux-x86_64 linux-aarch64; do
34+
CHECKSUM=$(grep -hrE "build/envcat-${VERSION}.${ARCH}$" sha256-*/checksums.txt | cut -d ' ' -f 1)
35+
36+
if [ -z "$CHECKSUM" ]; then
37+
ls -R
38+
cat sha256-*/checksums.txt
39+
echo "*** CHECKSUM ERROR OR BUILD VERSION MISMATCH ***"
40+
exit 1
41+
fi
42+
43+
cat <<EOF
44+
#### ${ARCH}
45+
46+
\`\`\`Dockerfile
47+
# Install envcat (${ARCH})
48+
ARG envcat_version=${VERSION}
49+
ARG envcat_sha256=${CHECKSUM}
50+
ADD --checksum=sha256:\${envcat_sha256} https://github.com/busyloop/envcat/releases/download/v\${envcat_version}/envcat-\${envcat_version}.${ARCH} /envcat
51+
RUN chmod +x /envcat
52+
\`\`\`
53+
54+
EOF
55+
done

.gitignore

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/docs/
2+
/lib/
3+
/bin/
4+
/build/
5+
/.shards/
6+
*.dwarf
7+
.DS_Store

.tool-versions

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
crystal 1.6.2

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2022 moe <[email protected]>
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Makefile

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
export UNAME := $(shell uname -sm | sed 's/ /-/' | tr '[:upper:]' '[:lower:]')
2+
export MAKE_UNAME := $(shell uname -sm | sed 's/ /_/' | tr '[:lower:]' '[:upper:]')
3+
export VERSION := $(shell grep "^version" shard.yml | cut -d ' ' -f 2)
4+
5+
SRC_FILES = $(shell find src)
6+
CRYSTAL ?= crystal
7+
CRYSTAL_SPEC_ARGS = --fail-fast
8+
9+
CRYSTAL_ARGS_LOCAL_DARWIN_X86_64 = --progress
10+
CRYSTAL_ARGS_LOCAL_LINUX_X86_64 = --progress
11+
CRYSTAL_ARGS_LOCAL_LINUX_AARCH64 = --progress
12+
CRYSTAL_ARGS_RELEASE_DARWIN_X86_64 = --release --no-debug
13+
CRYSTAL_ARGS_RELEASE_LINUX_X86_64 = --static --release --no-debug
14+
CRYSTAL_ARGS_RELEASE_LINUX_AARCH64 = --static --release --no-debug
15+
16+
DOCKER_IMAGE = 84codes/crystal:1.6.2-alpine
17+
ALPINE_VERSION = $(shell which apk)
18+
19+
EXE_SRC = src/envcat.cr
20+
EXE_BASENAME = envcat-$(VERSION)
21+
22+
.PHONY: init release
23+
24+
lint_and_test: lint test
25+
26+
test:
27+
$(CRYSTAL) spec $(CRYSTAL_SPEC_ARGS)
28+
29+
lint:
30+
bin/ameba
31+
32+
clean:
33+
rm -f build/*
34+
35+
build: build/$(EXE_BASENAME).$(UNAME)
36+
37+
release: test
38+
$(MAKE) build/$(EXE_BASENAME).$(UNAME) BUILD_MODE=RELEASE
39+
# mkdir -p build && date >build/$(EXE_BASENAME).$(UNAME)
40+
rm -f build/*.dwarf
41+
42+
release_linux:
43+
$(MAKE) release UNAME=linux-x86_64
44+
45+
ci:
46+
shards install --without-development
47+
48+
init:
49+
@mkdir -p build
50+
51+
tag:
52+
git tag v$(VERSION)
53+
54+
version:
55+
@echo $(VERSION)
56+
57+
prepare_alpine:
58+
ifeq ($(shell [[ ! -z "$(ALPINE_VERSION)" ]] && echo true),true)
59+
apk add yaml-static
60+
endif
61+
62+
# Static linux release build inside alpine
63+
build/$(EXE_BASENAME).linux-x86_64: $(SRC_FILES) | init prepare_alpine
64+
ifeq ($(shell [[ -z "$(ALPINE_VERSION)" && "$(BUILD_MODE)" == "RELEASE" ]] && echo true),true)
65+
time docker run --rm -it -w /src -v `pwd`:/src --entrypoint make $(DOCKER_IMAGE) $@ BUILD_MODE=RELEASE
66+
else
67+
$(CRYSTAL) build $(CRYSTAL_ARGS_$(or $(BUILD_MODE),LOCAL)_$(MAKE_UNAME)) -o $@ ${EXE_SRC}
68+
@ldd $@ 2>/dev/null && { echo "ERROR: Compiler did not produce a static executable - see http://bit.ly/3jnS5yV"; exit 1; } || true
69+
endif
70+
71+
build/$(EXE_BASENAME).%: $(SRC_FILES) | init prepare_alpine
72+
time $(CRYSTAL) build $(CRYSTAL_ARGS_$(or $(BUILD_MODE),LOCAL)_$(MAKE_UNAME)) -o $@ ${EXE_SRC}
73+
74+
README.md: docs/templates/README.md.j2 build/$(EXE_BASENAME).$(UNAME)
75+
HELP_SCREEN=$$(build/$(EXE_BASENAME).$(UNAME) --help 2>&1 | tac | tail -n +3 | tac | tail -n +2 | sed 's/\x1B\[[0-9;]\{1,\}[A-Za-z]//g') build/$(EXE_BASENAME).$(UNAME) -f j2 HELP_SCREEN VERSION <$^ >$@
76+
77+
README: README.md
78+
readme: README.md

0 commit comments

Comments
 (0)