diff --git a/.github/workflows/dagger_on_fly_docker.yml b/.github/workflows/dagger_on_fly_docker.yml new file mode 100644 index 0000000000..4dfb5be001 --- /dev/null +++ b/.github/workflows/dagger_on_fly_docker.yml @@ -0,0 +1,69 @@ +name: "Dagger on Fly.io Docker" + +on: + workflow_call: + secrets: + FLY_WIREGUARD: + required: true + +jobs: + run: + runs-on: ubuntu-latest + steps: + - name: "Checkout code..." + uses: actions/checkout@v3 + + # ⚠️ FLY_WIREGUARD is configured via `fly wireguard create ...` - see 2022.fly/docker/README.md + - name: "Set up WireGuard for Fly.io Docker Engine..." + run: | + echo "🔒 Install WireGuard & friends..." + sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends wireguard-tools openresolv + echo "🔐 Configure WireGuard tunnel..." + printf "${{ secrets.FLY_WIREGUARD }}" | sudo tee /etc/wireguard/fly.conf + sudo wg-quick up fly + echo "🩻 Check IPv6 routes..." + sudo ip -6 route list + echo "🩻 Check DNS resolution..." + sudo resolvconf -v + + - name: "Check remote Docker Engine..." + env: + DOCKER_ENGINE_HOST: ${{ vars.DOCKER_ENGINE_HOST }} + run: | + echo "🤨 Can we resolve ${DOCKER_ENGINE_HOST:?must be set} IPv6?" + dig +short "$DOCKER_ENGINE_HOST" AAAA + echo "🤨 Can we ping $DOCKER_ENGINE_HOST IPv6?" + ping6 -c 3 "$(dig +short $DOCKER_ENGINE_HOST AAAA)" + echo "🤨 Can we ping $DOCKER_ENGINE_HOST FQDN?" + ping6 -c 3 "$DOCKER_ENGINE_HOST" + echo "🤨 Can we connect to Docker running on $DOCKER_ENGINE_HOST?" + nc -vz6 "$DOCKER_ENGINE_HOST" 2375 + + - uses: actions/setup-go@v4 + with: + go-version: "1.20" + cache-dependency-path: "magefiles/go.sum" + + - name: "Build, test, publish & deploy..." + id: cicd + env: + DOCKER_HOST: "${{ vars.DOCKER_ENGINE_HOST_FQDN }}" + IMAGE_OWNER: "${{ vars.IMAGE_OWNER }}" + GHCR_USERNAME: "${{ github.actor }}" + GHCR_PASSWORD: "${{ secrets.GHCR_PASSWORD }}" + FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} + AWS_ACCESS_KEY_ID: "${{ secrets.AWS_ACCESS_KEY_ID }}" + AWS_SECRET_ACCESS_KEY: "${{ secrets.AWS_SECRET_ACCESS_KEY }}" + run: | + cd magefiles + go run main.go -w ../ ci cd + + - name: "Announce deploy in #dev Slack..." + if: ${{ github.repository == 'thechangelog/changelog.com' && github.ref_name == 'master' }} + uses: rtCamp/action-slack-notify@v2 + env: + MSG_MINIMAL: "commit,actions url" + SLACK_CHANNEL: dev + SLACK_USERNAME: "GitHub Actions" + SLACK_FOOTER: "Just got shipped to https://changelog.com" + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} diff --git a/.github/workflows/dagger_on_github.yml b/.github/workflows/dagger_on_github.yml new file mode 100644 index 0000000000..90d2fdcb63 --- /dev/null +++ b/.github/workflows/dagger_on_github.yml @@ -0,0 +1,38 @@ +name: "Dagger on GitHub" + +on: + workflow_call: + +jobs: + run: + runs-on: ubuntu-latest + steps: + - name: "Checkout code..." + uses: actions/checkout@v3 + + - uses: actions/setup-go@v4 + with: + go-version: "1.20" + cache-dependency-path: "magefiles/go.sum" + + - name: "Build, test, publish & deploy..." + env: + IMAGE_OWNER: "${{ vars.IMAGE_OWNER }}" + GHCR_USERNAME: "${{ github.actor }}" + GHCR_PASSWORD: "${{ secrets.GHCR_PASSWORD }}" + FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} + AWS_ACCESS_KEY_ID: "${{ secrets.AWS_ACCESS_KEY_ID }}" + AWS_SECRET_ACCESS_KEY: "${{ secrets.AWS_SECRET_ACCESS_KEY }}" + run: | + cd magefiles + go run main.go -w ../ ci cd + + - name: "Announce deploy in #dev Slack..." + if: ${{ github.repository == 'thechangelog/changelog.com' && github.ref_name == 'master' }} + uses: rtCamp/action-slack-notify@v2 + env: + MSG_MINIMAL: "commit,actions url" + SLACK_CHANNEL: dev + SLACK_USERNAME: "GitHub Actions" + SLACK_FOOTER: "Just got shipped to https://changelog.com" + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} diff --git a/.github/workflows/dagger_on_k8s.yml b/.github/workflows/dagger_on_k8s.yml new file mode 100644 index 0000000000..196ffae0e0 --- /dev/null +++ b/.github/workflows/dagger_on_k8s.yml @@ -0,0 +1,32 @@ +name: "Dagger on K8s" + +on: + workflow_call: + +jobs: + run: + runs-on: self-hosted + continue-on-error: true + steps: + - name: "Checkout code..." + uses: actions/checkout@v3 + + - uses: actions/setup-go@v4 + with: + go-version: "1.20" + cache-dependency-path: "magefiles/go.sum" + + - name: "Build, test, publish & deploy..." + env: + IMAGE_OWNER: "${{ vars.IMAGE_OWNER }}" + GHCR_USERNAME: "${{ github.actor }}" + GHCR_PASSWORD: "${{ secrets.GHCR_PASSWORD }}" + FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} + AWS_ACCESS_KEY_ID: "${{ secrets.AWS_ACCESS_KEY_ID }}" + AWS_SECRET_ACCESS_KEY: "${{ secrets.AWS_SECRET_ACCESS_KEY }}" + run: | + cd magefiles + go run main.go -w ../ ci + + # TODO: run this in Dagger + # - name: "Announce deploy in #dev Slack..." diff --git a/.github/workflows/ship_it.yml b/.github/workflows/ship_it.yml index cb5e63bc03..037e1fc9ae 100644 --- a/.github/workflows/ship_it.yml +++ b/.github/workflows/ship_it.yml @@ -1,5 +1,10 @@ name: "Ship It!" +concurrency: + # There should only be able one running job per repository / branch combo. + # We do not want multiple deploys running in parallel. + group: ${{ github.repository }}-${{ github.ref_name }} + on: push: branches: @@ -9,58 +14,32 @@ on: pull_request: workflow_dispatch: +# All jobs have the same outcome. We define multiple for resiliency reasons. jobs: - cicd: - runs-on: ubuntu-latest - steps: - - name: "Checkout code..." - uses: actions/checkout@v3 - - # ⚠️ FLY_WIREGUARD is configured via `fly wireguard create ...` - see 2022.fly/docker/README.md - - name: "Set up WireGuard for Fly.io Docker Engine..." - env: - FLY_WIREGUARD: ${{ secrets.FLY_WIREGUARD }} - if: "${{ env.FLY_WIREGUARD != '' }}" - run: | - sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends wireguard-tools openresolv - printf "${{ secrets.FLY_WIREGUARD }}" | sudo tee /etc/wireguard/fly.conf - sudo wg-quick up fly + # In thechangelog/changelog repository (a.k.a. upstream), + # this is the preferred default: + dagger-on-fly-docker: + if: ${{ contains(vars.RUNS_ON, 'fly') }} + uses: ./.github/workflows/dagger_on_fly_docker.yml + secrets: inherit - # ⚠️ IPv6 is configured via `fly ips private` - see 2022.fly/docker/README.md - - name: "Check Fly.io Docker Engine" - env: - DOCKER_ENGINE_HOST: ${{ secrets.DOCKER_ENGINE_HOST }} - if: "${{ env.DOCKER_ENGINE_HOST != '' }}" - run: | - ping6 -c 5 "$DOCKER_ENGINE_HOST" - nc -vz6 "$DOCKER_ENGINE_HOST" 2375 + # When our Fly.io setup misbehaves, we want a fallback: + dagger-on-github-fallback: + needs: dagger-on-fly-docker + if: ${{ failure() }} + uses: ./.github/workflows/dagger_on_github.yml + secrets: inherit - - uses: actions/setup-go@v4 - with: - go-version: "1.20" - - name: "Build, test, publish & deploy..." - env: - DOCKER_HOST: "${{ secrets.DOCKER_ENGINE_HOST_FQDN }}" - IMAGE_OWNER: "${{ secrets.IMAGE_OWNER }}" - GHCR_USERNAME: "${{ github.actor }}" - GHCR_PASSWORD: "${{ secrets.GHCR_PASSWORD }}" - FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} - AWS_ACCESS_KEY_ID: "${{ secrets.AWS_ACCESS_KEY_ID }}" - AWS_SECRET_ACCESS_KEY: "${{ secrets.AWS_SECRET_ACCESS_KEY }}" - run: | - cd magefiles - go run main.go -w ../ ci cd + # As forks will not have access to our Fly.io, + # we fallback to GitHub default: + dagger-on-github: + if: ${{ !contains(vars.RUNS_ON, 'fly') }} + uses: ./.github/workflows/dagger_on_github.yml + secrets: inherit - notify: - if: ${{ github.repository == 'thechangelog/changelog.com' && github.ref_name == 'master' }} - needs: cicd - runs-on: ubuntu-latest - steps: - - name: "Notify Slack about deploy..." - uses: rtCamp/action-slack-notify@v2 - env: - MSG_MINIMAL: "commit,actions url" - SLACK_CHANNEL: dev - SLACK_USERNAME: "GitHub Actions" - SLACK_FOOTER: "Just got shipped to https://changelog.com" - SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} + # This is an experimental job which only runs the CI part of our pipeline. + # In other words, this does not run CD, it does not deploy our app. + dagger-on-k8s: + if: ${{ contains(vars.RUNS_ON, 'k8s') }} + uses: ./.github/workflows/dagger_on_k8s.yml + secrets: inherit