@@ -3,129 +3,106 @@ permissions:
33 packages : write
44 contents : write
55on :
6- # Triggered on new GitHub Release
7- release :
8- types : [published]
9- # Triggered on every successful Build action
106 workflow_run :
11- workflows : ["Build"]
12- branches : [main,master]
7+ workflows : ["Build Container"]
138 types :
149 - completed
15- # Manual trigger for rollback to specific release or redeploy latest
10+ branches :
11+ - main
12+ - master
1613 workflow_dispatch :
17- inputs :
18- version :
19- default : latest
20- description : Tag you want to release.
21- required : true
14+
15+ env :
16+ DOCKER_BUILDKIT : 1
17+ KAMAL_REGISTRY_PASSWORD : ${{ secrets.GITHUB_TOKEN }}
18+ KAMAL_REGISTRY_USERNAME : ${{ github.actor }}
2219
2320jobs :
24- push_to_registry :
25- runs-on : ubuntu-22.04
26- if : ${{ github.event.workflow_run.conclusion != 'failure ' }}
21+ release :
22+ runs-on : ubuntu-latest
23+ if : ${{ github.event.workflow_run.conclusion == 'success ' }}
2724 steps :
28- # Checkout latest or specific tag
29- - name : checkout
30- if : ${{ github.event.inputs.version == '' || github.event.inputs.version == 'latest' }}
31- uses : actions/checkout@v3
32- - name : checkout tag
33- if : ${{ github.event.inputs.version != '' && github.event.inputs.version != 'latest' }}
25+ - name : Checkout code
3426 uses : actions/checkout@v3
35- with :
36- ref : refs/tags/${{ github.event.inputs.version }}
37-
38- # Assign environment variables used in subsequent steps
39- - name : Env variable assignment
40- run : echo "image_repository_name=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
41- # TAG_NAME defaults to 'latest' if not a release or manual deployment
42- - name : Assign version
27+
28+ - name : Set up environment variables
4329 run : |
44- echo "TAG_NAME=latest" >> $GITHUB_ENV
45- if [ "${{ github.event.release.tag_name }}" != "" ]; then
46- echo "TAG_NAME=${{ github.event.release.tag_name }}" >> $GITHUB_ENV
47- fi;
48- if [ "${{ github.event.inputs.version }}" != "" ]; then
49- echo "TAG_NAME=${{ github.event.inputs.version }}" >> $GITHUB_ENV
50- fi;
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+ if find . -maxdepth 2 -type f -name "Configure.Db.Migrations.cs" | grep -q .; then
35+ echo "HAS_MIGRATIONS=true" >> $GITHUB_ENV
36+ else
37+ echo "HAS_MIGRATIONS=false" >> $GITHUB_ENV
38+ fi
39+ if [ -n "${{ secrets.KAMAL_DEPLOY_IP }}" ]; then
40+ echo "HAS_DEPLOY_ACTION=true" >> $GITHUB_ENV
41+ else
42+ echo "HAS_DEPLOY_ACTION=false" >> $GITHUB_ENV
43+ fi
44+
45+ # This step is for the deployment of the templates only, safe to delete
46+ - name : Modify deploy.yml
47+ if : env.HAS_DEPLOY_ACTION == 'true'
48+ run : |
49+ sed -i "s/service: test/service: ${{ env.repository_name_lower }}/g" config/deploy.yml
50+ sed -i "s#image: my-user/test#image: ${{ env.image_repository_name }}#g" config/deploy.yml
51+ sed -i "s/- 192.168.0.1/- ${{ secrets.KAMAL_DEPLOY_IP }}/g" config/deploy.yml
52+ sed -i "s/host: test.example.com/host: ${{ secrets.KAMAL_DEPLOY_HOST }}/g" config/deploy.yml
53+ sed -i "s/Test/${{ env.repository_name }}/g" config/deploy.yml
5154
5255 - name : Login to GitHub Container Registry
53- uses : docker/login-action@v2
56+ uses : docker/login-action@v3
5457 with :
5558 registry : ghcr.io
56- username : ${{ github.actor }}
57- password : ${{ secrets.GITHUB_TOKEN }}
58-
59- # Build and push new docker image, skip for manual redeploy other than 'latest'
60- - name : Build and push Docker image
61- run : |
62- dotnet publish --os linux --arch x64 -c Release -p:ContainerRepository=${{ env.image_repository_name }} -p:ContainerRegistry=ghcr.io -p:ContainerImageTags=${{ env.TAG_NAME }} -p:ContainerPort=80
59+ username : ${{ env.KAMAL_REGISTRY_USERNAME }}
60+ password : ${{ env.KAMAL_REGISTRY_PASSWORD }}
6361
64- deploy_via_ssh :
65- needs : push_to_registry
66- runs-on : ubuntu-22.04
67- if : ${{ github.event.workflow_run.conclusion != 'failure' }}
68- steps :
69- # Checkout latest or specific tag
70- - name : checkout
71- if : ${{ github.event.inputs.version == '' || github.event.inputs.version == 'latest' }}
72- uses : actions/checkout@v3
73- - name : checkout tag
74- if : ${{ github.event.inputs.version != '' && github.event.inputs.version != 'latest' }}
75- uses : actions/checkout@v3
62+ - name : Set up SSH key
63+ uses : webfactory/ssh-agent@v0.9.0
7664 with :
77- ref : refs/tags/ ${{ github.event.inputs.version }}
65+ ssh-private-key : ${{ secrets.SSH_PRIVATE_KEY }}
7866
79- - name : repository name fix and env
67+ - name : Setup Ruby
68+ uses : ruby/setup-ruby@v1
69+ with :
70+ ruby-version : 3.3.0
71+ bundler-cache : true
72+
73+ - name : Install Kamal
74+ run : gem install kamal -v 2.3.0
75+
76+ - name : Set up Docker Buildx
77+ uses : docker/setup-buildx-action@v3
78+ with :
79+ driver-opts : image=moby/buildkit:master
80+
81+ - name : Kamal bootstrap
82+ run : kamal server bootstrap
83+
84+ - name : Check if first run and execute kamal app boot if necessary
8085 run : |
81- echo "image_repository_name=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
82- echo "TAG_NAME=latest" >> $GITHUB_ENV
83- if [ "${{ github.event.release.tag_name }}" != "" ]; then
84- echo "TAG_NAME=${{ github.event.release.tag_name }}" >> $GITHUB_ENV
85- fi;
86- if [ "${{ github.event.inputs.version }}" != "" ]; then
87- echo "TAG_NAME=${{ github.event.inputs.version }}" >> $GITHUB_ENV
88- fi;
86+ FIRST_RUN_FILE=".${{ env.repository_name }}"
87+ if ! kamal server exec --no-interactive -q "test -f $FIRST_RUN_FILE"; then
88+ kamal server exec --no-interactive -q "touch $FIRST_RUN_FILE" || true
89+ kamal deploy -q -P --version latest || true
90+ else
91+ echo "Not first run, skipping kamal app boot"
92+ fi
8993
90- - name : Create .env file
94+ - name : Ensure file permissions
9195 run : |
92- echo "Generating .env file"
93-
94- echo "# Autogenerated .env file" > .deploy/.env
95- echo "HOST_DOMAIN=${{ secrets.DEPLOY_HOST }}" >> .deploy/.env
96- echo "LETSENCRYPT_EMAIL=${{ secrets.LETSENCRYPT_EMAIL }}" >> .deploy/.env
97- echo "APP_NAME=${{ github.event.repository.name }}" >> .deploy/.env
98- echo "IMAGE_REPO=${{ env.image_repository_name }}" >> .deploy/.env
99- echo "RELEASE_VERSION=${{ env.TAG_NAME }}" >> .deploy/.env
100-
101- # Copy only the docker-compose.yml to remote server home folder
102- - name : copy files to target server via scp
103- uses : appleboy/scp-action@v0.1.3
104- with :
105- host : ${{ secrets.DEPLOY_HOST }}
106- username : ${{ secrets.DEPLOY_USERNAME }}
107- port : 22
108- key : ${{ secrets.DEPLOY_KEY }}
109- strip_components : 2
110- source : " ./.deploy/docker-compose.yml,./.deploy/.env"
111- target : " ~/.deploy/${{ github.event.repository.name }}/"
96+ kamal server exec --no-interactive "mkdir -p /opt/docker/${{ env.repository_name }}/App_Data && chown -R 1654:1654 /opt/docker/${{ env.repository_name }}"
11297
113- # Deploy Docker image with your application using `docker compose up` remotely
114- - name : remote docker-compose up via ssh
115- uses : appleboy/ssh-action@v0.1.5
116- env :
117- APPTOKEN : ${{ secrets.GITHUB_TOKEN }}
118- USERNAME : ${{ secrets.DEPLOY_USERNAME }}
119- with :
120- host : ${{ secrets.DEPLOY_HOST }}
121- username : ${{ secrets.DEPLOY_USERNAME }}
122- key : ${{ secrets.DEPLOY_KEY }}
123- port : 22
124- envs : APPTOKEN,USERNAME
125- script : |
126- echo $APPTOKEN | docker login ghcr.io -u $USERNAME --password-stdin
127- cd ~/.deploy/${{ github.event.repository.name }}
128- docker compose pull
129- export APP_ID=$(docker compose run --entrypoint "id -u" --rm app)
130- docker compose run --entrypoint "chown $APP_ID:$APP_ID /app/App_Data" --user root --rm app
131- docker compose up app -d
98+ - name : Migration
99+ if : env.HAS_MIGRATIONS == 'true'
100+ run : |
101+ kamal server exec --no-interactive 'echo "${{ env.KAMAL_REGISTRY_PASSWORD }}" | docker login ghcr.io -u ${{ env.KAMAL_REGISTRY_USERNAME }} --password-stdin'
102+ kamal server exec --no-interactive "docker pull ghcr.io/${{ env.image_repository_name }}:latest || true"
103+ kamal app exec --no-reuse --no-interactive --version=latest "--AppTasks=migrate"
104+
105+ - name : Deploy with Kamal
106+ run : |
107+ kamal lock release -v
108+ kamal deploy -P --version latest
0 commit comments