Next: Stack Actions #1761 #4244
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Build | |
on: | |
push: | |
branches: [main] | |
tags: ['v*'] | |
pull_request: | |
env: | |
TERM: xterm | |
DOTNET_SYSTEM_CONSOLE_ALLOW_ANSI_COLOR_REDIRECTION: true | |
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true | |
DOTNET_NOLOGO: true | |
MSBUILDTERMINALLOGGER: auto | |
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} | |
jobs: | |
version: | |
runs-on: ubuntu-latest | |
timeout-minutes: 30 | |
outputs: | |
version: ${{ steps.version.outputs.version }} | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Build Reason | |
env: | |
GITHUB_EVENT: ${{ toJson(github) }} | |
run: "echo ref: ${{github.ref}} event: ${{github.event_name}}" | |
- name: Setup .NET Core | |
uses: actions/setup-dotnet@v4 | |
with: | |
dotnet-version: 9.0.* | |
dotnet-quality: ga | |
- name: Version | |
id: version | |
run: | | |
dotnet tool install --global minver-cli --version 6.0.0 | |
version=$(minver --tag-prefix v) | |
echo "version=$version" >> $GITHUB_OUTPUT | |
echo "### $version" >> $GITHUB_STEP_SUMMARY | |
test-api: | |
runs-on: ubuntu-latest | |
timeout-minutes: 30 | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Setup .NET Core | |
uses: actions/setup-dotnet@v4 | |
with: | |
dotnet-version: 9.0.* | |
dotnet-quality: ga | |
- name: Start Services | |
working-directory: docker | |
run: docker compose up -d elasticsearch & | |
- uses: actions/cache@v4 | |
with: | |
path: ~/.nuget/packages | |
key: nuget-${{ runner.os }}-${{ hashFiles('**/packages.lock.json') }} | |
restore-keys: | | |
nuget-${{ runner.os }}- | |
- name: Nuget Restore | |
run: dotnet restore | |
- name: Build | |
run: dotnet build --no-restore --configuration Release | |
- name: Wait for Elasticsearch | |
working-directory: docker | |
run: docker compose up --wait elasticsearch | |
- name: Run .NET Tests | |
run: dotnet test --no-restore --no-build --configuration Release --collect:"XPlat Code Coverage" -m:1 --logger trx --results-directory coverage --logger GitHubActions | |
- name: Copy Coverage to Predictable Location | |
run: cp coverage/*/coverage.cobertura.xml coverage/coverage.cobertura.xml | |
- name: Code Coverage Summary Report | |
uses: irongut/[email protected] | |
with: | |
filename: coverage/coverage.cobertura.xml | |
badge: true | |
format: "markdown" | |
output: "both" | |
- name: Add Coverage PR Comment | |
uses: marocchino/sticky-pull-request-comment@v2 | |
if: github.event_name == 'pull_request' | |
with: | |
recreate: true | |
path: code-coverage-results.md | |
- name: Write Coverage to Job Summary | |
run: cat code-coverage-results.md >> $GITHUB_STEP_SUMMARY | |
test-client: | |
runs-on: ubuntu-latest | |
timeout-minutes: 30 | |
defaults: | |
run: | |
working-directory: src/Exceptionless.Web/ClientApp | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Setup Node.js environment | |
uses: actions/setup-node@v4 | |
with: | |
node-version: 20 | |
- name: Cache node_modules | |
uses: actions/cache@v4 | |
id: cache-node-modules | |
with: | |
path: src/Exceptionless.Web/ClientApp/node_modules | |
key: node-modules-${{ hashFiles('src/Exceptionless.Web/ClientApp/package-lock.json') }} | |
- name: Install Npm Packages | |
if: steps.cache-node-modules.outputs.cache-hit != 'true' | |
run: npm ci | |
- name: Lint Client | |
run: npm run lint | |
- name: Check | |
run: npm run check | |
- name: Build | |
run: npm run build | |
- name: Run Unit Tests | |
run: echo "npm run test:unit" | |
- name: Run Integration Tests | |
run: echo "npm run test:integration" | |
build-and-push-docker: | |
runs-on: ubuntu-latest | |
needs: [version] | |
timeout-minutes: 30 | |
env: | |
VERSION: ${{needs.version.outputs.version}} | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Set up Docker Buildx | |
if: "${{ env.DOCKER_USERNAME != '' }}" | |
uses: docker/setup-buildx-action@v3 | |
with: | |
platforms: linux/amd64 | |
- name: Build api docker image | |
run: | | |
echo "::remove-matcher owner=csc::" | |
docker buildx build . --target api --platform linux/amd64 --tag exceptionless/api-ci:latest --cache-from type=gha --cache-to type=gha,mode=max --load | |
- name: Build job docker image | |
run: | | |
echo "::remove-matcher owner=csc::" | |
docker buildx build . --target job --platform linux/amd64 --tag exceptionless/job-ci:latest --cache-from type=gha --cache-to type=gha,mode=max --load | |
- name: Build app docker image | |
run: | | |
echo "::remove-matcher owner=csc::" | |
docker buildx build . --target app --platform linux/amd64 --tag exceptionless/app-ci:latest --cache-from type=gha --cache-to type=gha,mode=max --load | |
- name: Build all-in-one docker image | |
run: | | |
echo "::remove-matcher owner=csc::" | |
docker buildx build . --target exceptionless --platform linux/amd64 --tag exceptionless/exceptionless-ci:latest --cache-from type=gha --cache-to type=gha,mode=max --load | |
- name: Build all-in-one Elasticsearch 7 docker image | |
if: "${{ env.DOCKER_USERNAME != '' && startsWith(github.ref, 'refs/tags/v') && github.event_name != 'pull_request' }}" | |
run: | | |
echo "::remove-matcher owner=csc::" | |
docker buildx build . --target exceptionless7 --platform linux/amd64 --tag exceptionless/exceptionless:latest-elasticsearch7 --cache-from type=gha --cache-to type=gha,mode=max --load | |
- name: Login to GitHub Container Registry | |
if: "${{ env.DOCKER_USERNAME != '' }}" | |
uses: docker/login-action@v3 | |
with: | |
registry: ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- name: Login to DockerHub | |
if: "${{ env.DOCKER_USERNAME != '' }}" | |
uses: docker/login-action@v3 | |
with: | |
username: ${{ env.DOCKER_USERNAME }} | |
password: ${{ secrets.DOCKER_PASSWORD }} | |
- name: Wait for test jobs # doing it this way so we don't have to copy artifacts between jobs | |
uses: yogeshlonkar/wait-for-jobs@v0 | |
with: | |
jobs: 'test-api,test-client' | |
interval: '2500' | |
ttl: '10' | |
- name: Publish CI Packages | |
if: "${{ env.DOCKER_USERNAME != '' }}" | |
run: | | |
echo "::remove-matcher owner=csc::" | |
# tag and push docker images | |
for image in {"api","job","app","exceptionless"}; do | |
docker image tag exceptionless/$image-ci:latest exceptionless/$image-ci:$VERSION | |
docker image tag exceptionless/$image-ci:latest ghcr.io/exceptionless/exceptionless/$image-ci:$VERSION | |
docker image tag exceptionless/$image-ci:latest ghcr.io/exceptionless/exceptionless/$image-ci:latest | |
docker image push --all-tags exceptionless/$image-ci | |
done | |
- name: Publish Release Packages | |
if: "${{ env.DOCKER_USERNAME != '' && startsWith(github.ref, 'refs/tags/v') && github.event_name != 'pull_request' }}" | |
run: | | |
echo "::remove-matcher owner=csc::" | |
# tag and push docker images | |
# only build elasticsearch 7 all-in-one image for release builds | |
docker image tag exceptionless/exceptionless:latest-elasticsearch7 exceptionless/exceptionless:$VERSION-elasticsearch7 | |
for image in {"api","job","app","exceptionless"}; do | |
docker image tag exceptionless/$image-ci:latest exceptionless/$image:$VERSION | |
docker image tag exceptionless/$image-ci:latest exceptionless/$image:latest | |
docker image push --all-tags exceptionless/$image | |
done | |
deploy: | |
if: "${{ (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')) && github.event_name != 'pull_request' }}" | |
needs: [version,build-and-push-docker] | |
runs-on: ubuntu-latest | |
timeout-minutes: 30 | |
env: | |
VERSION: ${{needs.version.outputs.version}} | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Install Helm | |
if: "${{ env.DOCKER_USERNAME != '' && github.event_name != 'pull_request' }}" | |
uses: azure/setup-helm@v4 | |
- name: Deploy Changes to Development Environment | |
if: "${{ env.DOCKER_USERNAME != '' && github.ref == 'refs/heads/main' && github.event_name != 'pull_request' }}" | |
run: | | |
az login --service-principal --username ${{ secrets.AZ_USERNAME }} --password ${{ secrets.AZ_PASSWORD }} --tenant ${{ secrets.AZ_TENANT }} --output none | |
az aks get-credentials --resource-group exceptionless-v6 --name ex-k8s-v6 | |
sed -i "s/^appVersion:.*$/appVersion: '${VERSION}'/" ./k8s/exceptionless/Chart.yaml | |
helm upgrade --set "version=${VERSION}" --reuse-values --values ./k8s/ex-dev-values.yaml ex-dev --namespace ex-dev ./k8s/exceptionless | |
- name: Deploy Changes to Production Environment | |
if: "${{ env.DOCKER_USERNAME != '' && startsWith(github.ref, 'refs/tags/v') && github.event_name != 'pull_request' }}" | |
run: | | |
az login --service-principal --username ${{ secrets.AZ_USERNAME }} --password ${{ secrets.AZ_PASSWORD }} --tenant ${{ secrets.AZ_TENANT }} --output none | |
az aks get-credentials --resource-group exceptionless-v6 --name ex-k8s-v6 | |
sed -i "s/^appVersion:.*$/appVersion: '${VERSION}'/" ./k8s/exceptionless/Chart.yaml | |
helm upgrade --set "version=${VERSION}" --reuse-values --values ./k8s/ex-prod-values.yaml ex-prod --namespace ex-prod ./k8s/exceptionless |