Skip to content

Merge pull request #11 from JourneyFlower/dev #164

Merge pull request #11 from JourneyFlower/dev

Merge pull request #11 from JourneyFlower/dev #164

name: Build Container
on:
push:
branches:
- main
- dev
paths:
- 'src/BE/**'
- 'src/FE/**'
- '.github/workflows/build-container.yml'
workflow_dispatch:
permissions:
contents: write
jobs:
build-fe:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Cache FE build output
id: fe_build_cache
uses: actions/cache@v4
with:
path: ./src/FE/out
key: ${{ runner.os }}-fe-build-${{ hashFiles('src/FE/**/*.json', 'src/FE/**/*.tsx', 'src/FE/**/*.ts', 'src/FE/**/*.svg', 'src/FE/**/*.png') }}
- name: Cache node_modules
id: node_modules_cache
if: steps.fe_build_cache.outputs.cache-hit != 'true'
uses: actions/cache@v4
with:
path: ./src/FE/node_modules
key: ${{ runner.os }}-fe-node_modules-${{ hashFiles('src/FE/package-lock.json') }}
- name: Install npm dependencies
if: steps.fe_build_cache.outputs.cache-hit != 'true' && steps.node_modules_cache.outputs.cache-hit != 'true'
working-directory: ./src/FE
run: npm i
- name: Build frontend
if: steps.fe_build_cache.outputs.cache-hit != 'true'
working-directory: ./src/FE
run: npm run build
- name: Upload FE build artifacts
uses: actions/upload-artifact@v4
with:
name: chats-fe
path: ./src/FE/out
build-primary-container:
needs: build-fe
runs-on: ubuntu-latest
steps:
- name: Login container
run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ vars.DOCKER_USERNAME }} ${{ vars.DOCKER_REGISTRY }} --password-stdin
- name: Checkout code
uses: actions/checkout@v4
- name: Download FE build artifacts
uses: actions/download-artifact@v4
with:
name: chats-fe
path: ./src/BE/wwwroot
- name: Build container
run: |
dotnet publish ./src/BE/Chats.BE.csproj -c Release --os linux --arch x64 /t:PublishContainer /p:ContainerRepository=chats
- name: Tag container with run number
run: |
docker tag chats ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:r${{ github.run_number }}-linux-x64
- name: Push container
run: |
docker push ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:r${{ github.run_number }}-linux-x64
build-containers:
if: github.ref == 'refs/heads/main'
needs: build-fe
strategy:
matrix:
include:
- tag: r${{ github.run_number }}-nanoserver-1809
runs-on: windows-latest
os: win
arch: x64
args: /p:ContainerBaseImage=mcr.microsoft.com/dotnet/aspnet:8.0-nanoserver-1809
- tag: r${{ github.run_number }}-nanoserver-ltsc2022
runs-on: windows-latest
os: win
arch: x64
args: /p:ContainerBaseImage=mcr.microsoft.com/dotnet/aspnet:8.0-nanoserver-ltsc2022
- tag: r${{ github.run_number }}-linux-arm64
runs-on: ubuntu-latest
os: linux
arch: arm64
runs-on: ${{ matrix.runs-on }}
steps:
- name: Login container
run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ vars.DOCKER_USERNAME }} ${{ vars.DOCKER_REGISTRY }} --password-stdin
- name: Checkout code
uses: actions/checkout@v4
- name: Download FE build artifacts
uses: actions/download-artifact@v4
with:
name: chats-fe
path: ./src/BE/wwwroot
- name: Build container
run: |
dotnet publish ./src/BE/Chats.BE.csproj -c Release --os ${{ matrix.os }} --arch ${{ matrix.arch }} /t:PublishContainer /p:ContainerRepository=chats ${{ matrix.args }}
- name: Tag container with run number
run: |
docker tag chats ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:${{ matrix.tag }}
- name: Push container
run: |
docker push ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:${{ matrix.tag }}
docker-manifest:
if: github.ref == 'refs/heads/main'
needs: [build-primary-container, build-containers]
runs-on: ubuntu-latest
steps:
- name: Login container
run: echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ vars.DOCKER_USERNAME }} ${{ vars.DOCKER_REGISTRY }} --password-stdin
- name: Create manifest
run: |
docker manifest create --amend ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:r${{ github.run_number }} \
${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:r${{ github.run_number }}-linux-x64 \
${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:r${{ github.run_number }}-linux-arm64 \
${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:r${{ github.run_number }}-nanoserver-1809 \
${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:r${{ github.run_number }}-nanoserver-ltsc2022
- name: Annotation
run: |
docker manifest annotate ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:r${{ github.run_number }} ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:r${{ github.run_number }}-nanoserver-1809 --os-version 10.0.17763.6532
docker manifest annotate ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:r${{ github.run_number }} ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:r${{ github.run_number }}-nanoserver-ltsc2022 --os-version 10.0.20348.2849
docker manifest inspect ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:r${{ github.run_number }}
- name: Create latest manifest
run: |
docker manifest create --amend ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:latest \
${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:r${{ github.run_number }}-linux-x64 \
${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:r${{ github.run_number }}-linux-arm64 \
${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:r${{ github.run_number }}-nanoserver-1809 \
${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:r${{ github.run_number }}-nanoserver-ltsc2022
- name: Annotate latest manifest
run: |
docker manifest annotate ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:latest ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:r${{ github.run_number }}-nanoserver-1809 --os-version 10.0.17763.6532
docker manifest annotate ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:latest ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:r${{ github.run_number }}-nanoserver-ltsc2022 --os-version 10.0.20348.2849
- name: Push manifest
run: |
docker manifest push ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:r${{ github.run_number }}
docker manifest push ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:latest
build-binaries:
if: github.ref == 'refs/heads/main'
needs: build-fe
strategy:
matrix:
include:
- id: chats
- id: chats-win-x64
args: -r win-x64 --self-contained true /p:PublishSingleFile=true /p:PublishReadyToRun=true /p:EnableCompressionInSingleFile=true
- id: chats-linux-x64
args: -r linux-x64 --self-contained true /p:PublishSingleFile=true /p:PublishReadyToRun=true /p:EnableCompressionInSingleFile=true
- id: chats-linux-arm64
args: -r linux-arm64 --self-contained true /p:PublishSingleFile=true /p:PublishReadyToRun=true /p:EnableCompressionInSingleFile=true
- id: chats-linux-musl-x64
args: -r linux-musl-x64 --self-contained true /p:PublishSingleFile=true /p:PublishReadyToRun=true /p:EnableCompressionInSingleFile=true
- id: chats-linux-musl-arm64
args: -r linux-musl-arm64 --self-contained true /p:PublishSingleFile=true /p:PublishReadyToRun=true /p:EnableCompressionInSingleFile=true
- id: chats-osx-arm64
args: -r osx-arm64 --self-contained true /p:PublishSingleFile=true /p:PublishReadyToRun=true /p:EnableCompressionInSingleFile=true
- id: chats-osx-x64
args: -r osx-x64 --self-contained true /p:PublishSingleFile=true /p:PublishReadyToRun=true /p:EnableCompressionInSingleFile=true
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download FE build artifacts
uses: actions/download-artifact@v4
with:
name: chats-fe
path: ./src/BE/wwwroot
- name: build binary
run: |
dotnet publish ./src/BE/Chats.BE.csproj -c Release -o ./Publish ${{ matrix.args }} /p:DeleteExistingFiles=True
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.id }}
path: ./Publish
create-release:
if: github.ref == 'refs/heads/main'
needs: [docker-manifest, build-binaries, upload-minio-latest]
runs-on: ubuntu-latest
outputs:
release_id: ${{ steps.create_release.outputs.release_id }}
steps:
- name: Get latest tag
id: get_latest_tag
uses: actions/github-script@v7
with:
script: |
const { data: tags } = await github.rest.repos.listTags({
owner: context.repo.owner,
repo: context.repo.repo,
per_page: 1,
});
let latestTag = "";
if (tags.length > 0) {
latestTag = tags[0].name;
}
core.setOutput('latestTag', latestTag);
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create Release
id: create_release
uses: actions/github-script@v7
with:
script: |
const latestTag = "${{ steps.get_latest_tag.outputs.latestTag }}";
const response = await github.rest.repos.createRelease({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: `r-${{ github.run_number }}`,
name: `r-${{ github.run_number }}`,
target_commitish: '${{ github.sha }}',
body: `### Full Changelogs
https://github.com/sdcb/chats/compare/${latestTag}...r-${{ github.run_number }}
### Docker
| Description | Docker Image |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------ |
| r${{ github.run_number }} | ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:r${{ github.run_number }} |
| Linux x64 | ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:r${{ github.run_number }}-linux-x64 |
| Linux ARM64 | ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:r${{ github.run_number }}-linux-arm64 |
| Windows Nano Server 1809 | ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:r${{ github.run_number }}-nanoserver-1809 |
| Windows Nano Server LTSC 2022 | ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:r${{ github.run_number }}-nanoserver-ltsc2022 |
| Latest | ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:latest |
### Alternative binaries download links that may faster than GitHub(for China users)
| Artifact | Download Link |
| -------------------------- | -------------------------------------------------------------------------------- |
| chats-win-x64.zip | ${{ vars.MINIO_URL }}/chats/r${{ github.run_number }}/chats-win-x64.zip |
| chats-linux-x64.zip | ${{ vars.MINIO_URL }}/chats/r${{ github.run_number }}/chats-linux-x64.zip |
| chats-linux-arm64.zip | ${{ vars.MINIO_URL }}/chats/r${{ github.run_number }}/chats-linux-arm64.zip |
| chats-linux-musl-x64.zip | ${{ vars.MINIO_URL }}/chats/r${{ github.run_number }}/chats-linux-musl-x64.zip |
| chats-linux-musl-arm64.zip | ${{ vars.MINIO_URL }}/chats/r${{ github.run_number }}/chats-linux-musl-arm64.zip |
| chats-osx-arm64.zip | ${{ vars.MINIO_URL }}/chats/r${{ github.run_number }}/chats-osx-arm64.zip |
| chats-osx-x64.zip | ${{ vars.MINIO_URL }}/chats/r${{ github.run_number }}/chats-osx-x64.zip |
| chats-fe.zip | ${{ vars.MINIO_URL }}/chats/r${{ github.run_number }}/chats-fe.zip |
| chats | ${{ vars.MINIO_URL }}/chats/r${{ github.run_number }}/chats |
**NOTE**:
Replace \`r${{ github.run_number }}\` with \`latest\` in the download link to get the latest version, for example: \`${{ vars.MINIO_URL }}/chats/latest/chats-win-x64.zip\`
`,
draft: false,
prerelease: false,
});
core.setOutput('release_id', response.data.id);
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
upload-release-assets:
if: github.ref == 'refs/heads/main'
strategy:
matrix:
include:
- asset: chats
- asset: chats-fe
- asset: chats-win-x64
- asset: chats-linux-x64
- asset: chats-linux-arm64
- asset: chats-linux-musl-x64
- asset: chats-linux-musl-arm64
- asset: chats-osx-arm64
- asset: chats-osx-x64
needs: create-release
runs-on: ubuntu-latest
steps:
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: ${{ matrix.asset }}
path: ${{ matrix.asset }}
- name: Compress artifacts into ZIP
run: |
zip -r ${{ matrix.asset }}.zip ${{ matrix.asset }}
shell: bash
- name: Upload Asset
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const assetPath = './${{ matrix.asset }}.zip';
const releaseId = "${{ needs.create-release.outputs.release_id }}";
const asset = fs.readFileSync(assetPath);
await github.rest.repos.uploadReleaseAsset({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: releaseId,
name: '${{ matrix.asset }}.zip',
data: asset,
});
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Delete build artifacts
uses: geekyeggo/delete-artifact@v5
with:
name: ${{ matrix.asset }}
upload-minio:
if: github.ref == 'refs/heads/main'
strategy:
matrix:
include:
- asset: chats
- asset: chats-fe
- asset: chats-win-x64
- asset: chats-linux-x64
- asset: chats-linux-arm64
- asset: chats-linux-musl-x64
- asset: chats-linux-musl-arm64
- asset: chats-osx-arm64
- asset: chats-osx-x64
needs: build-binaries
runs-on: ubuntu-latest
steps:
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: ${{ matrix.asset }}
path: ${{ matrix.asset }}
- name: Compress artifacts into ZIP
run: |
zip -r ${{ matrix.asset }}.zip ${{ matrix.asset }}
shell: bash
- name: Configure MINIO Credentials
run: |
echo "AWS_ACCESS_KEY_ID=${{ secrets.MINIO_KEY }}" >> $GITHUB_ENV
echo "AWS_SECRET_ACCESS_KEY=${{ secrets.MINIO_SECRET }}" >> $GITHUB_ENV
echo "AWS_DEFAULT_REGION=us-east-1" >> $GITHUB_ENV
- name: Upload to Minio
run: |
aws --endpoint-url ${{ vars.MINIO_URL }} s3 cp ${{ matrix.asset }}.zip s3://chats/r${{ github.run_number }}/${{ matrix.asset }}.zip
upload-minio-latest:
if: github.ref == 'refs/heads/main'
needs: upload-minio
runs-on: ubuntu-latest
steps:
- name: Configure MINIO Credentials
run: |
echo "AWS_ACCESS_KEY_ID=${{ secrets.MINIO_KEY }}" >> $GITHUB_ENV
echo "AWS_SECRET_ACCESS_KEY=${{ secrets.MINIO_SECRET }}" >> $GITHUB_ENV
echo "AWS_DEFAULT_REGION=us-east-1" >> $GITHUB_ENV
- name: Update latest files
run: |
aws --endpoint-url ${{ vars.MINIO_URL }} s3 rm s3://chats/latest --recursive
aws --endpoint-url ${{ vars.MINIO_URL }} s3 cp s3://chats/r${{ github.run_number }} s3://chats/latest --recursive
deploy-dev-stg:
runs-on: ubuntu-latest
needs: build-primary-container
steps:
- uses: webfactory/[email protected]
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
- name: deploy dev/stg
run: |
ssh -o StrictHostKeyChecking=no -p 22 ${{ secrets.SSH_TARGET }} << 'EOF'
docker pull ${{ vars.DOCKER_REGISTRY }}/${{ vars.DOCKER_NAMESPACE }}/chats:r${{ github.run_number }}-linux-x64
cd chats
sed -i "s/^TAG=.*/TAG=r${{ github.run_number }}-linux-x64/" ~/chats/dev.env
sed -i "s/^TAG=.*/TAG=r${{ github.run_number }}-linux-x64/" ~/chats/stg.env
./dev.sh && ./stg.sh
EOF