Skip to content

Commit 60d9793

Browse files
authored
Merge pull request #106 from cygni/Bump-to-latest
Bump to latest, Arena, CD, Digitalocean profile
2 parents 65d4fdf + 18b5dc9 commit 60d9793

31 files changed

+549
-111
lines changed

.dockerignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.gradle
2+
.idea
3+
.vscode
4+
build

.github/workflows/docker-image.yml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
name: Docker Image CD
2+
on:
3+
push:
4+
tags:
5+
- '*.*.*'
6+
branches: [ "master" ]
7+
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
steps:
12+
13+
- name: Check out the repo
14+
uses: actions/checkout@v3
15+
16+
- name: Login to Docker Hub
17+
uses: docker/login-action@v1
18+
with:
19+
username: ${{ secrets.DOCKER_HUB_USERNAME }}
20+
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
21+
22+
- name: Extract metadata (tags, labels) for Docker
23+
id: meta
24+
uses: docker/metadata-action@v4
25+
with:
26+
# set latest tag for main branch
27+
tags: |
28+
type=raw,value=latest
29+
type=ref,event=tag
30+
images: ${{ secrets.DOCKER_HUB_USERNAME }}/${{ github.event.repository.name }}
31+
32+
- name: Install doctl
33+
uses: digitalocean/action-doctl@v2
34+
with:
35+
token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
36+
37+
- name: Build and push Docker image
38+
id: docker_build
39+
uses: docker/build-push-action@v2
40+
with:
41+
context: .
42+
push: true
43+
# push main -> tag:latest, release x.x.x main -> tag:latest AND tag:x.x.x
44+
tags: ${{ steps.meta.outputs.tags }}
45+
labels: ${{ steps.meta.outputs.labels }}
46+
47+
# Pushing to production
48+
- name: Force rebuild in digitalocean
49+
run: doctl apps create-deployment ${{secrets.DIGITALOCEAN_APP_ID}} --force-rebuild --wait
50+
51+
- name: Get commit sha
52+
id: vars
53+
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
54+
55+
- name: Get current date
56+
id: date
57+
run: echo "::set-output name=date::$(date +'%Y-%m-%d')"
58+
59+
- name: Tag digitalocean yml name with date and sha
60+
uses: fjogeleit/[email protected]
61+
with:
62+
valueFile: 'digitalocean-spec.yaml'
63+
propertyPath: 'name'
64+
value: snakebot-${{steps.date.outputs.date}}-${{steps.vars.outputs.sha_short}}
65+
commitChange: false
66+
updateFile: true
67+
68+
- name: Update digitalocean app with new yml spec
69+
run: doctl apps update ${{ secrets.DIGITALOCEAN_APP_ID }} --spec digitalocean-spec.yaml

Dockerfile

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Build
2+
FROM gradle:7.4.2-jdk17
3+
WORKDIR /app
4+
COPY . .
5+
ENV PORT=8080
6+
EXPOSE 8080
7+
RUN gradle clean build
8+
9+
# Run
10+
FROM azul/zulu-openjdk:17-jre
11+
WORKDIR /app
12+
COPY --from=0 /app/app/build/libs/app-0.1.21.jar .
13+
14+
# To run in digitalocean profile, send in env variable PROFILE_FLAG=-Dspring.profiles.active=digitalocean
15+
# Note: There is a problem with the way this is setup. Ctrl+C will not work.
16+
# Using Spring Boot's environment variable did not work when we tried to use it.
17+
CMD java -jar $PROFILE_FLAG app-0.1.21.jar

README.md

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,42 @@
1-
# snakebot
1+
## Users
22

3-
[![Build Status](http://jenkins.snake.cygni.se/buildStatus/icon?job=snakebot)](http://jenkins.snake.cygni.se/job/snakebot/)
3+
If you are a user who **only** wants to code your own bot, then simply head to the [snakebot client respository](https://github.com/cygni/snakebot-client-js) and follow the instructions there. There will be a _docker-compose_ file there to easily get your own server and webclient running as containers without the need to clone them from here.
4+
5+
#
6+
7+
# SNAKEBOT
48

59
A multi player, server based snake game for computer bots as players
610

711
Clients connect via a websocket through which events and commands are sent bidirectionally.
8-
Several client implementations exist:
12+
Following client implementations are up to date:
13+
14+
<!-- - [Java](https://github.com/cygni/snakebot-client-java)
15+
- [.NET](https://github.com/cygni/snakebot-client-dotnet) -->
916

10-
- [Java](https://github.com/cygni/snakebot-client-java)
11-
- [.NET](https://github.com/cygni/snakebot-client-dotnet)
1217
- [JavaScript](https://github.com/cygni/snakebot-client-js)
13-
- [C++](https://github.com/cygni/snakebot-client-cpp)
18+
<!-- - [C++](https://github.com/cygni/snakebot-client-cpp)
1419
- [Rust](https://github.com/cygni/snakebot-client-rust)
1520
- [ClojureScript](https://github.com/cygni/snakebot-client-clojurescript)
16-
- [Go](https://github.com/cygni/snakebot-client-golang)
21+
- [Go](https://github.com/cygni/snakebot-client-golang) -->
22+
23+
#
24+
25+
### **Updates and Docker**
26+
27+
**IMPORTANT**: Commits on the **main** branch will launch an action that builds and **overrides** the docker image tagged as the latest on [DockerHub](https://hub.docker.com/repository/docker/cygni/snakebot). Therefore it is important to **ONLY** push changes to **main** that works and have been tested, to ensure that latest image works for anyone who wants to use it. If a commit is deemed **stable** you can also add a **tag** to that commit to ensure it remains on [DockerHub](https://hub.docker.com/repository/docker/cygni/snakebot) without getting overwritten. E.g creating a release with a tag will both push the newly build docker image with the tag latest **AND** the tag name given as long as it follows the standard **X.X.X** name.
28+
29+
Because of what mentioned above, when adding a new feature or changing some behavior, make sure to work on a **different branch** first before pushing to **main**.
30+
31+
### **Production**
32+
33+
**IMPORTANT**: Commits to the main branch will also act as commits towards production. Rebuilding the images on DockerHub through commits from main will cause the production server to reboot with the updated version of the image.
34+
35+
#
36+
37+
## To run locally
38+
39+
<br>
1740

1841
To clean and build:
1942

@@ -33,36 +56,36 @@ To run server locally with increased memory:
3356
> export JAVA_OPTS="-Xmx4096m" && ./gradlew bootRun
3457
```
3558

36-
To run packaged server with overridden setting for game link:
59+
<!-- To run packaged server with overridden setting for game link:
3760
3861
```
3962
> ./gradlew clean bootRepackage
4063
> java -Xmx4096m -Dsnakebot.view.url=http://<your-ip>:8090/#/viewgame/ -jar app/build/libs/snakebot-app-0.1.18.jar
41-
```
64+
``` -->
4265

43-
To generate Spring Boot self contained artifact:
66+
<!-- To generate Spring Boot self contained artifact:
4467
4568
```
4669
> ./gradlew clean bootRepackage
47-
```
70+
``` -->
4871

49-
To publish maven artifacts to repository:
72+
<!-- To publish maven artifacts to repository:
5073
5174
```
5275
> export mvn_snake_user='the_user'
5376
> export mvn_snake_pwd='the_pwd'
5477
> ./gradlew upload
55-
```
78+
``` -->
5679

57-
We're using a small java-app running on GCP: https://github.com/renaudcerrato/appengine-maven-repository
80+
<!-- We're using a small java-app running on GCP: https://github.com/renaudcerrato/appengine-maven-repository
5881
5982
If you change the client code/api and want to test locally, you need to publish your new snapshot locally before the code in the snake clients project can see your changes:
6083
6184
```
6285
> ./gradlew publishToMavenLocal
63-
```
86+
``` -->
6487

65-
## To test production-like environment locally
88+
<!-- ## To test production-like environment locally
6689
6790
Start ElasticSearch:
6891
@@ -88,4 +111,4 @@ Start the application from your IDE with production profile:
88111
-Dspring.profiles.active=production
89112
```
90113
91-
Create the Elasticsearch indexes by following these [instructions](app/docs/elasticsearch.md)
114+
Create the Elasticsearch indexes by following these [instructions](app/docs/elasticsearch.md) -->
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package se.cygni.snake.api.event;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
6+
import se.cygni.snake.api.GameMessage;
7+
import se.cygni.snake.api.type.GameMessageType;
8+
9+
@GameMessageType
10+
public class ArenaEndedEvent extends GameMessage {
11+
private final String arenaName;
12+
13+
@JsonCreator
14+
public ArenaEndedEvent(
15+
@JsonProperty("arenaName") String arenaName) {
16+
17+
this.arenaName = arenaName;
18+
}
19+
20+
public String getArenaName() {
21+
return arenaName;
22+
}
23+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package se.cygni.snake.api.exception;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
import se.cygni.snake.api.GameMessage;
6+
import se.cygni.snake.api.type.GameMessageType;
7+
8+
@GameMessageType
9+
public class ArenaIsFull extends GameMessage {
10+
11+
private int playersConnected;
12+
13+
@JsonCreator
14+
public ArenaIsFull(
15+
@JsonProperty("playersConnected") int playersConnected) {
16+
this.playersConnected = playersConnected;
17+
}
18+
19+
public int getPlayersConnected() {
20+
return playersConnected;
21+
}
22+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package se.cygni.snake.api.exception;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
import se.cygni.snake.api.GameMessage;
6+
import se.cygni.snake.api.type.GameMessageType;
7+
8+
@GameMessageType
9+
public class InvalidArenaName extends GameMessage {
10+
11+
public enum ArenaNameInvalidReason {
12+
Nonexistent,
13+
}
14+
15+
private ArenaNameInvalidReason reasonCode;
16+
17+
@JsonCreator
18+
public InvalidArenaName(
19+
@JsonProperty("ArenaNameInvalidReason") ArenaNameInvalidReason reasonCode) {
20+
this.reasonCode = reasonCode;
21+
}
22+
23+
public ArenaNameInvalidReason getReasonCode() {
24+
return reasonCode;
25+
}
26+
27+
}

api/src/main/java/se/cygni/snake/api/model/GameSettings.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
public class GameSettings {
44

55
// Maximum noof players in this game
6-
private int maxNoofPlayers = 5;
6+
private int maxNoofPlayers = 10;
77

88
// The starting length of a snake
99
private int startSnakeLength = 1;
@@ -237,7 +237,7 @@ public void setStartObstacles(int startObstacles) {
237237
}
238238

239239
public static class GameSettingsBuilder {
240-
private int maxNoofPlayers = 5;
240+
private int maxNoofPlayers = 10;
241241
private int startSnakeLength = 1;
242242
private int timeInMsPerTick = 250;
243243
private boolean obstaclesEnabled = true;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package se.cygni.snake.eventapi.request;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
6+
import se.cygni.snake.api.model.GameSettings;
7+
import se.cygni.snake.eventapi.ApiMessage;
8+
import se.cygni.snake.eventapi.type.ApiMessageType;
9+
10+
@ApiMessageType
11+
public class CreateArena extends ApiMessage {
12+
13+
private GameSettings gameSettings;
14+
15+
@JsonCreator
16+
public CreateArena(
17+
@JsonProperty("gameSettings") GameSettings gameSettings) {
18+
this.gameSettings = gameSettings;
19+
}
20+
21+
public GameSettings getGameSettings() {
22+
return gameSettings;
23+
}
24+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package se.cygni.snake.eventapi.request;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import se.cygni.snake.eventapi.ApiMessage;
5+
import se.cygni.snake.eventapi.type.ApiMessageType;
6+
7+
@ApiMessageType
8+
public class DisconnectFromArena extends ApiMessage {
9+
10+
@JsonCreator
11+
public DisconnectFromArena() {}
12+
13+
}

0 commit comments

Comments
 (0)