Skip to content

Commit e4d54f4

Browse files
committed
Make actions-ready
1 parent 9f6e0c9 commit e4d54f4

File tree

16 files changed

+169
-797
lines changed

16 files changed

+169
-797
lines changed

.github/dependabot.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
version: 2
77
updates:
8-
- package-ecosystem: "npm" # See documentation for possible values
9-
directory: "/" # Location of package manifests
10-
schedule:
11-
interval: "daily"
8+
- package-ecosystem: "npm" # See documentation for possible values
9+
directory: "/" # Location of package manifests
10+
schedule:
11+
interval: "daily"

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
.idea/
22
node_modules/
3-
dist/
43
*.iml
54
yarn-error.log
65
.env

.gitmodules

Lines changed: 0 additions & 3 deletions
This file was deleted.

README.md

Lines changed: 71 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
# Upload Unit
2-
Upload Unit is a GitHub Action to upload a unit to Cratecode. It handles uploading lessons, subunits, and units, all under a single repository.
2+
3+
Upload Unit is a GitHub Action to upload a unit to Cratecode. It handles uploading lessons, subunits, and units, all under a single action.
4+
5+
# Examples
6+
7+
## Upload a Manifest
8+
9+
```yaml
10+
steps:
11+
- uses: actions/checkout@v2
12+
13+
- uses: cratecode/upload-manifest@v1
14+
with:
15+
manifest: path/to/manifest
16+
key: ${{ secrets.CRATECODE_API_KEY }}
17+
```
18+
19+
# Usage
320
421
Uploading works by creating a manifest file which imports other manifest files, and can also specify a unit to upload. This "root" manifest file commonly links to either subunits (which in turn link to lessons or other subunits) or lessons, which will be uploaded.
522
@@ -8,42 +25,69 @@ Instead of working with IDs directly, items are linked and mapped with "friendly
825
Units can reference lessons or other units. If you need to use someone else's unit/lesson, you can use their ID by starting the ID with a ":" and placing it in the friendly name field.
926
1027
Unit manifest files contain the definition for the unit. That is, they include a starting lesson for the unit, and what lessons other lessons point to. They follow the following format:
28+
1129
```json
1230
{
13-
"type": "unit",
14-
"id": "Friendly Name",
15-
"name": "Display Name",
16-
"upload": [
17-
"folder1/manifest.json"
18-
],
19-
"start": "first_lesson",
20-
"lessons": {
21-
"first_lesson": {
22-
"next": "next_lesson",
23-
"requires": []
24-
},
25-
"next_lesson": {
26-
"next": [],
27-
"requires": [
28-
"next_lesson"
29-
]
31+
"type": "unit",
32+
"id": "Friendly Name",
33+
"name": "Display Name",
34+
"upload": ["folder1/manifest.json"],
35+
"start": "first_lesson",
36+
"lessons": {
37+
"first_lesson": {
38+
"next": "next_lesson"
39+
},
40+
"next_lesson": {
41+
"next": []
42+
}
3043
}
31-
}
3244
}
3345
```
3446

3547
Lesson manifest files include information about the lesson. They should be included in the directory containing the lesson's contents. For example, a lesson manifest might be in a folder that looks like:
48+
3649
```
37-
folder
38-
-- index.js
39-
-- manifest.json
40-
-- README.md
50+
folder/
51+
-- index.js
52+
-- manifest.json
53+
-- README.md
4154
```
55+
4256
During the uploading process, the manifest will not be uploaded. For a lesson manifest, the following format is used:
57+
4358
```json
4459
{
45-
"type": "lesson",
46-
"id": "Friendly Name",
47-
"name": "Display Name"
60+
"type": "lesson",
61+
"id": "Friendly Name",
62+
"name": "Display Name"
4863
}
49-
```
64+
```
65+
66+
A typical setup might look like the below file tree, where the first manifest is the first example manifest and the second manifest is the second example manifest:
67+
68+
```
69+
folder/
70+
-- manifest.json
71+
-- lessons/
72+
-- lesson_1/
73+
-- index.js
74+
-- manifest.json
75+
-- README.md
76+
```
77+
78+
You may also subdivide your unit into multiple smaller units. In the example below, the first two manifests are unit manifests (like the first example manifest), while the second is a lesson manifest (like the second example manifest). In this example, the first manifest may upload the second manifest and link to the unit described by the second manifest, while the second manifest may upload the third and link to the lesson described by the third.
79+
80+
```
81+
folder/
82+
-- manifest.json
83+
-- units/
84+
-- unit_1/
85+
-- manifest.json
86+
-- lessons/
87+
-- lesson_1/
88+
-- index.js
89+
-- manifest.json
90+
-- README.md
91+
```
92+
93+
As you can see, many configurations are possible. To look at an actual example, please head over to the [Cratecode Intro](https://github.com/Cratecode/intro.git) repository.

action.yml

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,13 @@ name: "Upload Unit"
22
description: "Uploads a unit to Cratecode, as well as any included lessons."
33
author: "Cratecode"
44
inputs:
5-
key:
6-
required: true
7-
description: "The API Key."
8-
manifest:
9-
required: true
10-
description: "The manifest file to use to upload."
11-
default: "manifest.json"
12-
domain:
13-
required: false
14-
description: "The domain to upload to."
15-
default: "https://cratecode.com"
16-
websocket:
17-
required: false
18-
description: "The websocket location."
19-
default: "wss://cratecode.com/container/"
5+
key:
6+
required: true
7+
description: "The API Key."
8+
manifest:
9+
required: true
10+
description: "The manifest file to use to upload."
11+
default: "manifest.json"
2012
runs:
21-
using: "node16"
22-
main: "dist/index.js"
13+
using: "node16"
14+
main: "dist/index.js"

build-proto.sh

Lines changed: 0 additions & 8 deletions
This file was deleted.

dist/index.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"use strict";
2+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3+
if (k2 === undefined) k2 = k;
4+
var desc = Object.getOwnPropertyDescriptor(m, k);
5+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6+
desc = { enumerable: true, get: function() { return m[k]; } };
7+
}
8+
Object.defineProperty(o, k2, desc);
9+
}) : (function(o, m, k, k2) {
10+
if (k2 === undefined) k2 = k;
11+
o[k2] = m[k];
12+
}));
13+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14+
Object.defineProperty(o, "default", { enumerable: true, value: v });
15+
}) : function(o, v) {
16+
o["default"] = v;
17+
});
18+
var __importStar = (this && this.__importStar) || function (mod) {
19+
if (mod && mod.__esModule) return mod;
20+
var result = {};
21+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22+
__setModuleDefault(result, mod);
23+
return result;
24+
};
25+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27+
return new (P || (P = Promise))(function (resolve, reject) {
28+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31+
step((generator = generator.apply(thisArg, _arguments || [])).next());
32+
});
33+
};
34+
Object.defineProperty(exports, "__esModule", { value: true });
35+
const core = __importStar(require("@actions/core"));
36+
const client_1 = require("@cratecode/client");
37+
(() => __awaiter(void 0, void 0, void 0, function* () {
38+
const manifest = core.getInput("manifest");
39+
const key = core.getInput("key");
40+
yield (0, client_1.upload)(manifest, key);
41+
}))();

package.json

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,25 @@
11
{
2-
"name": "upload-unit",
3-
"version": "1.0.0",
4-
"scripts": {
5-
"build": "tsc",
6-
"proto": "./build-proto.sh"
7-
},
8-
"description": "A GitHub Action for uploading a unit to Cratecode.",
9-
"main": "index.js",
10-
"repository": "https://github.com/Cratecode/upload-unit.git",
11-
"author": "Cratecode",
12-
"license": "Apache-2.0",
13-
"dependencies": {
14-
"@actions/core": "^1.9.0",
15-
"axios": "^0.27.2",
16-
"form-data": "^4.0.0",
17-
"walkdir": "^0.4.1",
18-
"ws": "^8.8.0"
19-
},
20-
"devDependencies": {
21-
"@protobuf-ts/plugin": "^2.6.0",
22-
"@types/node": "^18.0.0",
23-
"@types/ws": "^8.5.3",
24-
"@typescript-eslint/eslint-plugin": "^5.28.0",
25-
"@typescript-eslint/parser": "^5.28.0",
26-
"eslint": "^8.17.0",
27-
"prettier": "^2.7.0",
28-
"typescript": "^4.7.3"
29-
},
30-
"optionalDependencies": {
31-
"bufferutil": "^4.0.6",
32-
"utf-8-validate": "^5.0.9"
33-
}
2+
"name": "upload-unit",
3+
"version": "1.0.0",
4+
"scripts": {
5+
"build": "tsc"
6+
},
7+
"description": "A GitHub Action for uploading a unit to Cratecode.",
8+
"main": "index.js",
9+
"repository": "https://github.com/Cratecode/upload-unit.git",
10+
"author": "Cratecode",
11+
"license": "Apache-2.0",
12+
"dependencies": {
13+
"@actions/core": "^1.9.0",
14+
"@cratecode/client": "^1.0.6"
15+
},
16+
"devDependencies": {
17+
"@types/node": "^18.0.0",
18+
"@typescript-eslint/eslint-plugin": "^5.28.0",
19+
"@typescript-eslint/parser": "^5.28.0",
20+
"eslint": "^8.17.0",
21+
"prettier": "^2.7.0",
22+
"typescript": "^4.7.3"
23+
},
24+
"optionalDependencies": {}
3425
}

protobuf

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/index.ts

Lines changed: 3 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,9 @@
11
import * as core from "@actions/core";
2-
import { readManifest } from "./manifest";
3-
import { websockets } from "./lesson";
2+
import { upload } from "@cratecode/client";
43

54
(async () => {
65
const manifest = core.getInput("manifest");
6+
const key = core.getInput("key");
77

8-
const state = {
9-
itemCount: 0,
10-
idsMap: {},
11-
};
12-
13-
// Open the initial manifest.
14-
await readManifest(state, null, null, manifest);
15-
16-
// Now, we should clean up websockets. If all websockets are closed, we can safely exit
17-
// the program, otherwise we should wait 30 seconds, then force close them and force exit after 5 seconds.
18-
if (websockets.some((ws) => ws.readyState !== ws.CLOSED)) {
19-
setTimeout(() => {
20-
for (const ws of websockets) {
21-
if (ws.readyState !== ws.CLOSED) {
22-
ws.close();
23-
}
24-
}
25-
26-
setTimeout(() => {
27-
process.exit(0);
28-
}, 5000);
29-
}, 30 * 1000);
30-
}
8+
await upload(manifest, key);
319
})();
32-
33-
/**
34-
* The application's state.
35-
*/
36-
export interface State {
37-
/**
38-
* The number of requests sent.
39-
*/
40-
itemCount: number;
41-
/**
42-
* A map from friendly names to IDs.
43-
*/
44-
idsMap: Record<string, string>;
45-
}
46-
47-
/**
48-
* Sleeps for a delay.
49-
* @param ms {number} - is the amount of time to sleep for.
50-
*/
51-
export function sleep(ms: number): Promise<void> {
52-
return new Promise((resolve) => {
53-
setTimeout(resolve, ms);
54-
});
55-
}
56-
57-
/**
58-
* Delays if the ratelimit has been hit.
59-
* @param state {State} - is the state.
60-
*/
61-
export async function delay(state: State): Promise<void> {
62-
if (++state.itemCount % 50 === 0) {
63-
console.log("Hit ratelimit, sleeping.");
64-
await sleep(60 * 1000);
65-
console.log("Waking up.");
66-
}
67-
}

0 commit comments

Comments
 (0)