Skip to content

Commit bfd122c

Browse files
authored
Workflows (#4)
* Dockerfile Signed-off-by: Mikhail Agapov <mikhail.agapov@decentraland.org> * Introduce GenerateProto mode to bundle the generated files for CI/Docker Signed-off-by: Mikhail Agapov <mikhail.agapov@decentraland.org> * Update .gitignore Signed-off-by: Mikhail Agapov <mikhail.agapov@decentraland.org> * workflows Signed-off-by: Mikhail Agapov <mikhail.agapov@decentraland.org> * Build in PRs Signed-off-by: Mikhail Agapov <mikhail.agapov@decentraland.org> * Add debuggability to local and remote docker deployments Signed-off-by: Mikhail Agapov <mikhail.agapov@decentraland.org> * Deploy-dev-debug workflow Signed-off-by: Mikhail Agapov <mikhail.agapov@decentraland.org> --------- Signed-off-by: Mikhail Agapov <mikhail.agapov@decentraland.org>
1 parent 053b0ff commit bfd122c

28 files changed

+12448
-18
lines changed

.dockerignore

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
**/.dockerignore
2+
**/.env
3+
**/.git
4+
**/.gitignore
5+
**/.project
6+
**/.settings
7+
**/.toolstarget
8+
**/.vs
9+
**/.vscode
10+
**/.idea
11+
**/*.*proj.user
12+
**/*.dbmdl
13+
**/*.jfm
14+
**/bin
15+
**/obj
16+
**/node_modules
17+
**/Dockerfile*
18+
**/docker-compose*
19+
**/compose*
20+
**/BenchmarkDotNet.Artifacts
21+
.claude/
22+
.github/
23+
src/DCLPulseTests/
24+
src/DCLPulseBenchmarks/
25+
LICENSE
26+
README.md
27+
CLAUDE.md
28+
tools/
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: Build Executable
2+
3+
on:
4+
workflow_dispatch:
5+
pull_request:
6+
types:
7+
- opened
8+
- reopened
9+
- synchronize
10+
push:
11+
branches:
12+
- "main"
13+
14+
concurrency:
15+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
16+
cancel-in-progress: true
17+
18+
jobs:
19+
build:
20+
strategy:
21+
matrix:
22+
include:
23+
- rid: linux-x64
24+
os: ubuntu-latest
25+
- rid: win-x64
26+
os: windows-latest
27+
- rid: osx-arm64
28+
os: macos-latest
29+
runs-on: ${{ matrix.os }}
30+
name: Build ${{ matrix.rid }}
31+
steps:
32+
- uses: actions/checkout@v4
33+
34+
- uses: actions/setup-dotnet@v4
35+
with:
36+
dotnet-version: "10.0.x"
37+
38+
- name: Publish
39+
run: >
40+
dotnet publish src/DCLPulse/DCLPulse.csproj
41+
-c Release
42+
-r ${{ matrix.rid }}
43+
--self-contained
44+
-p:PublishSingleFile=true
45+
-p:GenerateProto=false
46+
-o ./artifacts/${{ matrix.rid }}
47+
48+
- uses: actions/upload-artifact@v4
49+
with:
50+
name: dcl-pulse-${{ matrix.rid }}
51+
path: ./artifacts/${{ matrix.rid }}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
name: Deploy Dev (Debug)
2+
3+
on:
4+
workflow_dispatch:
5+
6+
jobs:
7+
cd-dcl-pulse-debug:
8+
uses: decentraland/platform-actions/.github/workflows/apps-docker-next.yml@main
9+
with:
10+
service-name: dcl-pulse
11+
dockerfile-url: https://raw.githubusercontent.com/decentraland/Pulse/main/src/DCLPulse/Dockerfile.dev-debug
12+
deployment-environment: dev
13+
secrets: inherit

.github/workflows/docker-next.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: CI/CD on main branch
2+
3+
on:
4+
push:
5+
branches:
6+
- "main"
7+
8+
jobs:
9+
cd-dcl-pulse:
10+
uses: decentraland/platform-actions/.github/workflows/apps-docker-next.yml@main
11+
with:
12+
service-name: dcl-pulse
13+
dockerfile-url: https://raw.githubusercontent.com/decentraland/Pulse/main/src/DCLPulse/Dockerfile
14+
deployment-environment: dev
15+
secrets: inherit
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: Publish 'latest' image
2+
3+
on:
4+
release:
5+
types:
6+
- "created"
7+
8+
jobs:
9+
cd-dcl-pulse:
10+
uses: decentraland/platform-actions/.github/workflows/apps-docker-release.yml@main
11+
with:
12+
service-name: dcl-pulse
13+
dockerfile-url: https://raw.githubusercontent.com/decentraland/Pulse/main/src/DCLPulse/Dockerfile
14+
deployment-environment: prd
15+
secrets: inherit
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Manual Deploy
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
deployment-environment:
7+
required: true
8+
type: choice
9+
options:
10+
- dev
11+
- prd
12+
default: prd
13+
description: Environment
14+
tag:
15+
required: true
16+
default: "latest"
17+
type: string
18+
description: "Docker tag (quay.io)"
19+
20+
jobs:
21+
deployment:
22+
if: ${{ inputs.deployment-environment }}
23+
name: Deploy dcl-pulse to ${{ inputs.deployment-environment }}
24+
runs-on: ubuntu-latest
25+
environment: ${{ inputs.deployment-environment }}
26+
steps:
27+
- name: Trigger deployment
28+
id: deploy
29+
uses: decentraland/dcl-deploy-action@main
30+
with:
31+
dockerImage: "quay.io/decentraland/dcl-pulse:${{ inputs.tag }}"
32+
serviceName: "dcl-pulse"
33+
env: ${{ inputs.deployment-environment }}
34+
token: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/test.yml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
name: Tests
2+
3+
on:
4+
workflow_dispatch:
5+
pull_request:
6+
types:
7+
- opened
8+
- reopened
9+
- synchronize
10+
push:
11+
branches:
12+
- "main"
13+
14+
permissions:
15+
contents: read
16+
checks: write
17+
actions: read
18+
19+
concurrency:
20+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
21+
cancel-in-progress: true
22+
23+
jobs:
24+
test:
25+
name: Run tests
26+
runs-on: ubuntu-latest
27+
steps:
28+
- uses: actions/checkout@v4
29+
30+
- uses: actions/setup-dotnet@v4
31+
with:
32+
dotnet-version: "10.0.x"
33+
34+
- name: Restore
35+
run: dotnet restore src/DCLPulse/DCLPulse.sln
36+
37+
- name: Build
38+
run: dotnet build src/DCLPulse/DCLPulse.sln -c Release --no-restore -p:GenerateProto=false
39+
40+
- name: Test
41+
run: >
42+
dotnet test src/DCLPulse/DCLPulse.sln
43+
-c Release
44+
--no-build
45+
--logger "trx;LogFileName=results.trx"
46+
-p:GenerateProto=false
47+
48+
- name: Report test results
49+
if: always()
50+
uses: dorny/test-reporter@v2.1.1
51+
with:
52+
name: Test Results
53+
path: "**/results.trx"
54+
reporter: dotnet-trx
55+
fail-on-error: true
56+
fail-on-empty: true
57+
use-actions-summary: true
58+
59+
- uses: actions/upload-artifact@v4
60+
if: always()
61+
with:
62+
name: test-results
63+
path: "**/results.trx"
64+
if-no-files-found: error

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
## Proto generated output
2-
src/Protocol/Generated/
1+
## Proto generation stamp (regenerated on build, not needed in VCS)
2+
src/Protocol/Generated/.proto.stamp
33

44
## Proto code-generation tooling stamp files (produced during build)
55
tools/protoc-gen-bitwise/.pip.stamp

Dockerfile.debug

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS debug
2+
WORKDIR /app
3+
RUN apt-get update && apt-get install -y curl unzip procps \
4+
&& curl -sSL https://aka.ms/getvsdbgsh | bash /dev/stdin -v latest -l /vsdbg \
5+
&& rm -rf /var/lib/apt/lists/*
6+
COPY . .
7+
EXPOSE 7777/udp
8+
ENTRYPOINT ["dotnet", "run", "--project", "src/DCLPulse/DCLPulse.csproj", "--configuration", "Debug", "--property:GenerateProto=false"]

README.md

Lines changed: 105 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,110 @@
33

44
## Protocol generation
55

6-
Protocol is auto-generated from the "protocol" directory, from "common" and "pulse" subdirs.
6+
Protocol C# files are auto-generated from the sibling [protocol](https://github.com/decentraland/protocol/tree/quantization) repo using `protoc` + the `protoc-gen-bitwise` plugin.
77

8-
It should reside on the same level as the root of the repo. You can modify `Directory.Build.props` to point to another location.
8+
### Prerequisites
99

10-
The protocol branch should start off from "quantization" branch https://github.com/decentraland/protocol/tree/quantization.
10+
The `protocol` repo must be checked out as a sibling of this repo:
11+
12+
```
13+
D:\<root>\protocol\ ← @dcl/protocol (quantization branch)
14+
D:\<root>\Pulse\ ← this repo
15+
```
16+
17+
You can override the path via `Directory.Build.props` or `-p:_ProtocolRepo=<path>`.
18+
19+
### GenerateProto switch
20+
21+
The `Protocol.csproj` has a `GenerateProto` property that controls whether `.proto` files are regenerated at build time or the committed `Generated/` files are used as-is.
22+
23+
| Mode | When to use | What happens |
24+
|------|------------|--------------|
25+
| `GenerateProto=true` (default) | Local development with the `protocol` repo available | Runs `protoc` + bitwise plugin, regenerates `src/Protocol/Generated/` |
26+
| `GenerateProto=false` | Docker builds, CI, or when the `protocol` repo is not available | Skips generation, compiles committed `Generated/*.cs` files directly |
27+
28+
To build without generation:
29+
30+
```bash
31+
dotnet build -p:GenerateProto=false
32+
```
33+
34+
After modifying `.proto` files, build normally (or explicitly with `GenerateProto=true`) and commit the updated `Generated/` files so Docker and CI builds stay in sync.
35+
36+
#### Rider
37+
38+
To set `GenerateProto` from Rider:
39+
40+
- **Solution-wide:** Settings → Build, Execution, Deployment → Toolset and Build → MSBuild CLI arguments → add `-p:GenerateProto=false`
41+
- **Per configuration:** Run → Edit Configurations → select configuration → Before launch → click the build step → add `-p:GenerateProto=false` to MSBuild arguments
42+
43+
In practice the default (`true`) is correct for local development. The `false` value is used by Docker/CI builds that don't have the protocol repo available.
44+
45+
## Docker debugging
46+
47+
### Start the debug container
48+
49+
```bash
50+
docker compose -f docker-compose.debug.yml up --build
51+
```
52+
53+
Wait for the server to log that it is listening on port 7777. The `src/` directory is volume-mounted — after editing source, restart the container to pick up changes (`docker compose -f docker-compose.debug.yml restart`).
54+
55+
### Attach Rider
56+
57+
1. Run → Edit Configurations → **+****.NET Attach to Remote Process**
58+
2. Connection type: **Docker container**
59+
3. Container: `dcl-pulse-debug`
60+
4. vsdbg path: `/vsdbg`
61+
5. Path mapping: local `./src` ↔ container `/app/src` (usually resolved automatically via the volume mount; set manually if Rider misses it)
62+
63+
Use **logpoints over breakpoints** for networking code (right-click gutter → Add Logpoint). They log to the Debug console without pausing the ENet tick loop or disconnecting clients.
64+
65+
### Quick reference
66+
67+
| Action | Command |
68+
|---|---|
69+
| Start | `docker compose -f docker-compose.debug.yml up --build` |
70+
| Tail logs | `docker logs -f dcl-pulse-debug` |
71+
| Rebuild | `docker compose -f docker-compose.debug.yml up --build --force-recreate` |
72+
| Stop | `docker compose -f docker-compose.debug.yml down` |
73+
| Connect client | `127.0.0.1:7777` |
74+
75+
### Remote debugging (dev environment)
76+
77+
The **Deploy Dev (Debug)** workflow (`deploy-dev-debug.yml`) deploys a debug-capable image to the dev environment. Trigger it manually from the GitHub Actions UI.
78+
79+
The debug image includes vsdbg and full debug symbols but runs on the slim `dotnet/runtime` base (not the SDK), so it's close to production weight.
80+
81+
#### Connecting Rider via ECS Exec
82+
83+
1. Find the running task:
84+
85+
```bash
86+
aws ecs list-tasks --cluster <cluster> --service-name dcl-pulse --query 'taskArns[0]' --output text
87+
```
88+
89+
2. Verify ECS Exec is enabled and attach:
90+
91+
```bash
92+
aws ecs execute-command \
93+
--cluster <cluster> \
94+
--task <task-id> \
95+
--container dcl-pulse \
96+
--interactive \
97+
--command "/bin/bash"
98+
```
99+
100+
3. In Rider: Run → Edit Configurations → **+****.NET Attach to Remote Process**
101+
- Connection type: **Custom pipe**
102+
- Pipe command: `aws ecs execute-command --cluster <cluster> --task <task-id> --container dcl-pulse --interactive --command`
103+
- Debugger path: `/vsdbg/vsdbg`
104+
- Path mapping: local `src/` ↔ container `/app/`
105+
106+
4. Select the `dotnet` process from the process list.
107+
108+
Prefer **logpoints over breakpoints** — a breakpoint pauses the ENet tick loop and disconnects all clients.
109+
110+
#### Reverting to production
111+
112+
After debugging, push to `main` or run the **Manual Deploy** workflow to redeploy the production image.

0 commit comments

Comments
 (0)