Skip to content

Commit f376d69

Browse files
committed
Add vue-static minimal template
1 parent a4f9f52 commit f376d69

File tree

183 files changed

+12116
-0
lines changed

Some content is hidden

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

183 files changed

+12116
-0
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
name: Build Container
2+
permissions:
3+
packages: write
4+
contents: write
5+
on:
6+
workflow_run:
7+
workflows: ["Build"]
8+
types:
9+
- completed
10+
branches:
11+
- main
12+
- master
13+
workflow_dispatch:
14+
15+
# Only update envs here if you need to change them for this workflow
16+
env:
17+
DOCKER_BUILDKIT: 1
18+
KAMAL_DEPLOY_HOST: ${{ secrets.KAMAL_DEPLOY_HOST }}
19+
20+
jobs:
21+
build-container:
22+
runs-on: ubuntu-latest
23+
if: ${{ github.event.workflow_run.conclusion == 'success' }}
24+
steps:
25+
- name: Checkout code
26+
uses: actions/checkout@v5
27+
28+
- name: Set up environment variables
29+
run: |
30+
echo "image_repository_name=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
31+
echo "repository_name=$(echo ${{ github.repository }} | cut -d '/' -f 2)" >> $GITHUB_ENV
32+
echo "repository_name_lower=$(echo ${{ github.repository }} | cut -d '/' -f 2 | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
33+
echo "org_name=$(echo ${{ github.repository }} | cut -d '/' -f 1)" >> $GITHUB_ENV
34+
35+
# Set SERVICE_LABEL: derive from GITHUB_REPOSITORY (replace dots with dashes)
36+
echo "SERVICE_LABEL=$(echo ${{ github.repository }} | cut -d '/' -f 2 | tr '.' '-')" >> $GITHUB_ENV
37+
38+
# Set KAMAL_DEPLOY_HOST: use secret if available, otherwise use repository name
39+
if [ -n "${{ secrets.KAMAL_DEPLOY_HOST }}" ]; then
40+
DEPLOY_HOST="${{ secrets.KAMAL_DEPLOY_HOST }}"
41+
else
42+
DEPLOY_HOST="$(echo ${{ github.repository }} | cut -d '/' -f 2)"
43+
fi
44+
45+
# Validate KAMAL_DEPLOY_HOST contains at least one '.'
46+
if [[ ! "$DEPLOY_HOST" == *.* ]]; then
47+
echo "Error: KAMAL_DEPLOY_HOST must contain a hostname, e.g. example.com (got: $DEPLOY_HOST)"
48+
exit 1
49+
fi
50+
51+
echo "KAMAL_DEPLOY_HOST=$DEPLOY_HOST" >> $GITHUB_ENV
52+
53+
# This step is for the deployment of the templates only, safe to delete
54+
- name: Modify csproj for template deploy
55+
env:
56+
KAMAL_DEPLOY_IP: ${{ secrets.KAMAL_DEPLOY_IP }}
57+
if: env.KAMAL_DEPLOY_IP != null
58+
run: |
59+
sed -i 's#<ContainerLabel Include="service" Value="my-app" />#<ContainerLabel Include="service" Value="${{ env.repository_name_lower }}" />#g' MyApp/MyApp.csproj
60+
61+
- name: Check for Client directory and package.json
62+
id: check_client
63+
run: |
64+
if [ -d "MyApp.Client" ] && [ -f "MyApp.Client/package.json" ]; then
65+
echo "client_exists=true" >> $GITHUB_OUTPUT
66+
else
67+
echo "client_exists=false" >> $GITHUB_OUTPUT
68+
fi
69+
70+
- name: Setup Node.js
71+
if: steps.check_client.outputs.client_exists == 'true'
72+
uses: actions/setup-node@v3
73+
with:
74+
node-version: 24
75+
76+
- name: Install npm dependencies
77+
if: steps.check_client.outputs.client_exists == 'true'
78+
working-directory: ./MyApp.Client
79+
run: npm install
80+
81+
- name: Build client
82+
if: steps.check_client.outputs.client_exists == 'true'
83+
working-directory: ./MyApp.Client
84+
run: npm run build
85+
86+
- name: Install x tool
87+
run: dotnet tool install -g x
88+
89+
- name: Apply Production AppSettings
90+
env:
91+
APPSETTINGS_PATCH: ${{ secrets.APPSETTINGS_PATCH }}
92+
if: env.APPSETTINGS_PATCH != null
93+
working-directory: ./MyApp
94+
run: |
95+
cat <<EOF >> appsettings.json.patch
96+
${{ secrets.APPSETTINGS_PATCH }}
97+
EOF
98+
x patch appsettings.json.patch
99+
100+
- name: Login to GitHub Container Registry
101+
uses: docker/login-action@v3
102+
with:
103+
registry: ghcr.io
104+
username: ${{ github.actor }}
105+
password: ${{ secrets.GITHUB_TOKEN }}
106+
107+
- name: Setup .NET
108+
uses: actions/setup-dotnet@v5
109+
with:
110+
dotnet-version: 10.0.x
111+
112+
- name: Build and push Docker image
113+
env:
114+
SERVICESTACK_LICENSE: ${{ secrets.SERVICESTACK_LICENSE }}
115+
KAMAL_DEPLOY_HOST: ${{ secrets.KAMAL_DEPLOY_HOST }}
116+
run: |
117+
dotnet publish --os linux --arch x64 -c Release \
118+
-p:ContainerRepository=${{ env.image_repository_name }} \
119+
-p:ContainerRegistry=ghcr.io -p:ContainerImageTags=latest \
120+
-p:ContainerPort=80 \
121+
-p:ContainerEnvironmentVariable="SERVICESTACK_LICENSE=${{ env.SERVICESTACK_LICENSE }}"

.github/workflows/build.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: Build
2+
3+
on:
4+
pull_request: {}
5+
push:
6+
branches:
7+
- '**' # matches every branch
8+
9+
jobs:
10+
build:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- name: checkout
14+
uses: actions/checkout@v5
15+
16+
- name: Setup dotnet
17+
uses: actions/setup-dotnet@v5
18+
with:
19+
dotnet-version: 10.0.x
20+
21+
- name: Restore NuGet packages
22+
run: dotnet restore MyApp.slnx
23+
24+
# If your feed requires authentication, enable and configure the step below.
25+
# This example uses a Personal Access Token stored in secrets.NUGET_API_KEY.
26+
# Alternatively, you can use the NuGet Authenticate action from Azure Pipelines.
27+
# - name: Authenticate private NuGet feed
28+
# env:
29+
# NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
30+
# run: |
31+
# dotnet nuget add source "https://YOUR_FEED_URL/index.json" \
32+
# --name "PrivateFeed" \
33+
# --username "YOUR_USERNAME" \
34+
# --password "$NUGET_API_KEY" \
35+
# --store-password-in-clear-text
36+
37+
- name: build
38+
run: dotnet build --no-restore
39+
working-directory: .
40+
41+
- name: test
42+
run: |
43+
dotnet test
44+
if [ $? -eq 0 ]; then
45+
echo TESTS PASSED
46+
else
47+
echo TESTS FAILED
48+
exit 1
49+
fi
50+
working-directory: ./MyApp.Tests
51+

.github/workflows/release.yml

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
name: Release
2+
permissions:
3+
packages: write
4+
contents: write
5+
on:
6+
workflow_run:
7+
workflows: ["Build Container"]
8+
types:
9+
- completed
10+
branches:
11+
- main
12+
- master
13+
workflow_dispatch:
14+
15+
env:
16+
DOCKER_BUILDKIT: 1
17+
SERVICESTACK_LICENSE: ${{ secrets.SERVICESTACK_LICENSE }}
18+
KAMAL_DEPLOY_IP: ${{ secrets.KAMAL_DEPLOY_IP }}
19+
KAMAL_DEPLOY_HOST: ${{ secrets.KAMAL_DEPLOY_HOST }}
20+
KAMAL_REGISTRY_USERNAME: ${{ github.actor }}
21+
KAMAL_REGISTRY_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
22+
23+
jobs:
24+
release:
25+
runs-on: ubuntu-latest
26+
if: ${{ github.event.workflow_run.conclusion == 'success' }}
27+
steps:
28+
- name: Checkout code
29+
uses: actions/checkout@v5
30+
31+
- name: Set up environment variables
32+
run: |
33+
echo "image_repository_name=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
34+
echo "repository_name=$(echo ${{ github.repository }} | cut -d '/' -f 2)" >> $GITHUB_ENV
35+
echo "repository_name_lower=$(echo ${{ github.repository }} | cut -d '/' -f 2 | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
36+
echo "org_name=$(echo ${{ github.repository }} | cut -d '/' -f 1)" >> $GITHUB_ENV
37+
if find . -maxdepth 2 -type f -name "Configure.Db.Migrations.cs" | grep -q .; then
38+
echo "HAS_MIGRATIONS=true" >> $GITHUB_ENV
39+
else
40+
echo "HAS_MIGRATIONS=false" >> $GITHUB_ENV
41+
fi
42+
43+
- name: Login to GitHub Container Registry
44+
uses: docker/login-action@v3
45+
with:
46+
registry: ghcr.io
47+
username: ${{ github.actor }}
48+
password: ${{ secrets.GITHUB_TOKEN }}
49+
50+
- name: Set up SSH key
51+
uses: webfactory/[email protected]
52+
with:
53+
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
54+
55+
- name: Setup Ruby
56+
uses: ruby/setup-ruby@v1
57+
with:
58+
ruby-version: 3.3.0
59+
bundler-cache: true
60+
61+
- name: Install Kamal
62+
run: gem install kamal -v 2.3.0
63+
64+
- name: Set up Docker Buildx
65+
uses: docker/setup-buildx-action@v3
66+
with:
67+
driver-opts: image=moby/buildkit:master
68+
69+
- name: Kamal bootstrap
70+
run: |
71+
kamal server bootstrap
72+
73+
- name: Ensure directories exist with correct permissions
74+
run: |
75+
echo "Creating directories with correct permissions"
76+
kamal server exec "mkdir -p /opt/docker/${{ env.repository_name }}/App_Data /opt/docker/${{ env.repository_name }}/initdb.d"
77+
78+
echo "Setting app file permissions"
79+
kamal server exec "chown -R 1654:1654 /opt/docker/${{ env.repository_name }}/App_Data /opt/docker/${{ env.repository_name }}/initdb.d"
80+
81+
- name: Check if first run and execute kamal app boot if necessary
82+
run: |
83+
FIRST_RUN_FILE="~/first-run/${{ env.repository_name }}"
84+
if ! kamal server exec -q "test -f $FIRST_RUN_FILE"; then
85+
kamal server exec -q "mkdir -p ~/first-run && touch $FIRST_RUN_FILE" || true
86+
87+
if [ -n "${{env.INIT_DB_SQL}}" ]; then
88+
echo "Initializing DB with INIT_DB_SQL secret..."
89+
# Save the SQL content to a temporary file
90+
echo "${{ env.INIT_DB_SQL }}" > init-db.sql
91+
cat init-db.sql | kamal server exec -i "cat > /opt/docker/${{ env.repository_name }}/initdb.d/${{ env.repository_name }}.sql" && rm init-db.sql || true
92+
fi
93+
# Start all kamal accessories
94+
kamal accessory boot all || true
95+
96+
# Deploy latest version
97+
kamal deploy -q -P --version latest || true
98+
else
99+
echo "Not first run, skipping kamal app boot"
100+
fi
101+
102+
- name: Verify file permissions before deploy
103+
run: |
104+
kamal server exec --no-interactive "chown -R 1654:1654 /opt/docker/${{ env.repository_name }}/App_Data /opt/docker/${{ env.repository_name }}/initdb.d"
105+
106+
- name: Deploy with Kamal
107+
run: |
108+
kamal lock release -v
109+
kamal server exec --no-interactive 'echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin'
110+
kamal server exec --no-interactive 'docker pull ghcr.io/${{ env.image_repository_name }}:latest'
111+
kamal deploy -P --version latest
112+
113+
- name: Migration
114+
if: env.HAS_MIGRATIONS == 'true'
115+
run: |
116+
kamal app exec --no-reuse --no-interactive --version=latest "--AppTasks=migrate"

0 commit comments

Comments
 (0)