Build and Deploy #106
This file contains hidden or 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 and Deploy | |
| on: | |
| push: | |
| branches: | |
| - master | |
| pull_request: | |
| branches: | |
| - master | |
| workflow_dispatch: | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME: vtvz/rustify | |
| jobs: | |
| validate: | |
| name: Validation | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| run: rustup show | |
| - name: Cache cargo registry | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cargo/registry | |
| key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock', 'rust-toolchain.toml') }} | |
| - name: Cache cargo index | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cargo/git | |
| key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock', 'rust-toolchain.toml') }} | |
| - name: Cache cargo build | |
| uses: actions/cache@v4 | |
| with: | |
| path: target | |
| key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock', 'rust-toolchain.toml') }} | |
| - name: Check formatting | |
| run: cargo fmt --all -- --check | |
| - name: Run clippy | |
| run: cargo clippy --all-targets --all-features --no-deps -- -D warnings | |
| - name: Run tests | |
| run: cargo test | |
| build: | |
| name: Build and Push | |
| runs-on: ubuntu-latest | |
| needs: validate | |
| if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' | |
| permissions: | |
| contents: read | |
| packages: write | |
| outputs: | |
| image_tag: ${{ steps.meta.outputs.image_tag }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Generate metadata | |
| id: meta | |
| run: | | |
| GIT_COMMIT=$(git rev-parse --verify HEAD) | |
| GIT_COMMIT_TIMESTAMP=$(git show --no-patch --format=%cI) | |
| GIT_DESCRIBE=$(git describe --abbrev=10 --always) | |
| IMAGE_TAG="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${GIT_DESCRIBE}" | |
| echo "git_commit=${GIT_COMMIT}" >> $GITHUB_OUTPUT | |
| echo "git_commit_timestamp=${GIT_COMMIT_TIMESTAMP}" >> $GITHUB_OUTPUT | |
| echo "git_describe=${GIT_DESCRIBE}" >> $GITHUB_OUTPUT | |
| echo "image_tag=${IMAGE_TAG}" >> $GITHUB_OUTPUT | |
| - name: Build and push lyrics-provider image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: ./lyrics-provider | |
| push: true | |
| tags: ${{ steps.meta.outputs.image_tag }}-lyrics-provider | |
| build-args: | | |
| GIT_SHA=${{ steps.meta.outputs.git_commit }} | |
| GIT_COMMIT_TIMESTAMP=${{ steps.meta.outputs.git_commit_timestamp }} | |
| GIT_DESCRIBE=${{ steps.meta.outputs.git_describe }} | |
| cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache-lyrics-provider | |
| cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache-lyrics-provider,mode=max | |
| - name: Build and push main image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| push: true | |
| tags: ${{ steps.meta.outputs.image_tag }} | |
| build-args: | | |
| GIT_SHA=${{ steps.meta.outputs.git_commit }} | |
| GIT_COMMIT_TIMESTAMP=${{ steps.meta.outputs.git_commit_timestamp }} | |
| GIT_DESCRIBE=${{ steps.meta.outputs.git_describe }} | |
| cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache | |
| cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max | |
| deploy: | |
| name: Deploy with Ansible | |
| runs-on: ubuntu-latest | |
| needs: build | |
| if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' | |
| environment: | |
| name: production | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.x" | |
| - name: Install Ansible | |
| run: | | |
| pip install ansible | |
| - name: Setup Ansible inventory | |
| run: | | |
| mkdir -p _infra/ansible/inventory/main/group_vars | |
| echo "${{ secrets.ANSIBLE_HOSTS_INI }}" | base64 -d > _infra/ansible/inventory/main/hosts.ini | |
| echo "${{ secrets.ANSIBLE_GROUP_VARS_ALL }}" | base64 -d > _infra/ansible/inventory/main/group_vars/all.yml | |
| - name: Setup SSH | |
| run: | | |
| mkdir -p ~/.ssh | |
| echo "${{ secrets.ANSIBLE_SSH_PRIVATE_KEY }}" > ~/.ssh/deploy_key | |
| echo "${{ secrets.ANSIBLE_SSH_CONFIG }}" | base64 -d > ~/.ssh/config | |
| chmod 600 ~/.ssh/deploy_key | |
| - name: Install Ansible Galaxy requirements | |
| working-directory: _infra/ansible | |
| run: ansible-galaxy install -r requirements.yml | |
| - name: Run Ansible playbook | |
| working-directory: _infra/ansible | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "False" | |
| ANSIBLE_DISPLAY_ARGS_TO_STDOUT: "False" | |
| ANSIBLE_DISPLAY_SKIPPED_HOSTS: "False" | |
| ANSIBLE_ANY_ERRORS_FATAL: "true" | |
| run: | | |
| ansible-playbook \ | |
| -i inventory/main/hosts.ini \ | |
| -e rustify_docker_image="${{ needs.build.outputs.image_tag }}" \ | |
| -t project \ | |
| --private-key ~/.ssh/deploy_key \ | |
| playbook.yml |