diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..e89ae93 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,74 @@ +name: ci +on: + push: +jobs: + build: + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/master' + permissions: + contents: write + outputs: + artifact_source_url: ${{ steps.upload.outputs.sunsetglow_artifact_url }} + env: + ACTIONS_ALLOW_UNSECURE_COMMANDS: true + steps: + - uses: actions/checkout@v3 + - uses: cachix/install-nix-action@v20 + - uses: cachix/cachix-action@v12 + with: + name: sunsetglow + authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' + - name: Build Nix + run: nix build -j8 .#devShells.x86_64-linux.build + - name: Build Website + run: nix develop .#devShells.x86_64-linux.build --command make build + - name: Create Tarball + run: nix develop .#devShells.x86_64-linux.build --command bash -c '(cd dist/ && tar -czvf ../sunsetglow.tar.gz *)' + - name: Create release and upload tarball + id: upload + run: | + commit_sha="$(git rev-parse --short HEAD)" + timestamp="$(date +%Y-%m-%d_%H-%M-%S)" + release_name="sunsetglow-${timestamp}-${commit_sha}" + token=${{ secrets.GITHUB_TOKEN }} + + # https://docs.github.com/en/rest/releases/releases#create-a-release + # https://stackoverflow.com/questions/45240336/how-to-use-github-release-api-to-make-a-release-without-source-code + upload_url="$(curl -s -H "Authorization: token $token" \ + -d "{\"tag_name\": \"$release_name\", \"name\":\"$release_name\",\"target_comitish\": \"$commit_sha\"}" \ + "https://api.github.com/repos/azuline/sunsetglow/releases" | jq -r '.upload_url')" + upload_url="${upload_url%\{*}" + echo "Created release $release_name" + + artifact_url="$(curl -s -H "Authorization: token $token" \ + -H "Content-Type: application/gzip" \ + --data-binary @sunsetglow.tar.gz \ + "$upload_url?name=sunsetglow.tar.gz&label=sunsetglow.tar.gz" | jq -r '.browser_download_url')" + echo "Uploaded sunsetglow.tar.gz to release" + + echo "sunsetglow_artifact_url=${artifact_url}" + echo "sunsetglow_artifact_url=${artifact_url}" >> $GITHUB_OUTPUT + deploy: + runs-on: ubuntu-latest + needs: build + env: + ACTIONS_ALLOW_UNSECURE_COMMANDS: true + ARTIFACT_SOURCE_URL: ${{ needs.build.outputs.artifact_source_url }} + NOMAD_ADDR: http://100.84.146.55:4646 + NOMAD_NAMESPACE: sunsetglow + NOMAD_TOKEN: ${{ secrets.NOMAD_TOKEN }} + steps: + - uses: actions/checkout@v3 + - uses: cachix/install-nix-action@v20 + - uses: cachix/cachix-action@v12 + with: + name: sunsetglow + authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' + - name: Tailscale + uses: tailscale/github-action@v1 + with: + authkey: ${{ secrets.TAILSCALE_AUTHKEY }} + - name: Build Nix + run: nix build -j8 .#devShells.x86_64-linux.deploy + - name: Deploy + run: nix develop .#devShells.x86_64-linux.deploy --command levant deploy -log-level=debug -var "artifact_source_url=$ARTIFACT_SOURCE_URL" deploy.nomad diff --git a/deploy.nomad b/deploy.nomad new file mode 100644 index 0000000..47e2e7a --- /dev/null +++ b/deploy.nomad @@ -0,0 +1,72 @@ +job "sunsetglow-site" { + datacenters = ["frieren"] + namespace = "sunsetglow" + type = "service" + + group "sunsetglow-site" { + count = 1 + + network { + mode = "bridge" + } + + service { + name = "sunsetglow-site" + port = "80" + connect { + sidecar_service {} + } + check { + expose = true + type = "http" + path = "/health" + interval = "10s" + timeout = "2s" + } + } + + task "sunsetglow-site" { + driver = "docker" + config { + image = "nginx" + volumes = [ + "local/dist:/www", + "local/nginx.conf:/etc/nginx/conf.d/default.conf", + ] + } + artifact { + source = "[[.artifact_source_url]]" + destination = "local/dist" + } + template { + data = < str: def empty_dist() -> None: # Removing and recreating the directory messes with the `make watch+serve` workflow. So we - # instead empty the directory each time.. - for f in Path("dist/").iterdir(): + # instead empty the directory each time if it already exists. + p = Path("dist") + if not p.is_dir(): + if p.is_file(): + p.unlink() + p.mkdir() + for f in p.iterdir(): if f.is_file(): f.unlink() elif f.is_dir(): shutil.rmtree(f) else: raise Exception(f"{f} is not a file or directory.") - Path("dist/").mkdir(exist_ok=True) def compile_posts():