exercism-config 0.60.0 → 0.65.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/rubocop.yml +2 -2
- data/.github/workflows/tests.yml +13 -2
- data/Gemfile +2 -0
- data/README.md +2 -1
- data/bin/setup_exercism_local_aws +0 -113
- data/exercism_config.gemspec +1 -0
- data/lib/exercism-config.rb +20 -0
- data/lib/exercism/config.rb +1 -1
- data/lib/exercism/tooling_job.rb +151 -0
- data/lib/exercism_config/version.rb +1 -1
- data/settings/ci.yml +10 -0
- data/settings/docker.yml +10 -0
- data/settings/local.yml +16 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f4ee8bd41a5f762b518a5510028a4b913c87390a8fa74bb10f7f0d295d3efff5
|
4
|
+
data.tar.gz: 48d18aa707cd2f1562412d57763427d08c8a2bd58d2da428a23e346dcf9fcb83
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 005bc9e61b363021dcd154791a623d99c4bcac9732211ab64f9c2851a75b660c5973c7d224d80f7258fd01a29e6f4119ce846f1f8ccbdc71e6bd482f4ae88617
|
7
|
+
data.tar.gz: 63b50fb4d9e4b0faffab1926ad244bc975af3361136525dc0a3e521f02e3fad4b2df03f86f242d794136b4e0ea043f82a846e91a2a49bac107d38fc20cff6aa4
|
data/.github/workflows/tests.yml
CHANGED
@@ -2,9 +2,9 @@ name: Tests
|
|
2
2
|
|
3
3
|
on:
|
4
4
|
push:
|
5
|
-
branches: [
|
5
|
+
branches: [main]
|
6
6
|
pull_request:
|
7
|
-
branches: [
|
7
|
+
branches: [main]
|
8
8
|
|
9
9
|
jobs:
|
10
10
|
test:
|
@@ -16,6 +16,16 @@ jobs:
|
|
16
16
|
ports:
|
17
17
|
- 4566
|
18
18
|
|
19
|
+
redis:
|
20
|
+
image: redis
|
21
|
+
ports:
|
22
|
+
- 6379:6379
|
23
|
+
options: >-
|
24
|
+
--health-cmd "redis-cli ping"
|
25
|
+
--health-interval 1s
|
26
|
+
--health-timeout 2s
|
27
|
+
--health-retries 10
|
28
|
+
|
19
29
|
steps:
|
20
30
|
###
|
21
31
|
# Checkout using GitHub's checkout action
|
@@ -38,6 +48,7 @@ jobs:
|
|
38
48
|
AWS_PORT: ${{ job.services.aws.ports['4566'] }}
|
39
49
|
run: |
|
40
50
|
bundle exec setup_exercism_config
|
51
|
+
bundle exec setup_exercism_local_aws
|
41
52
|
|
42
53
|
###
|
43
54
|
# Setup code climate
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -36,9 +36,10 @@ Exercism.secrets.hcaptcha_secret
|
|
36
36
|
Exercism.dynamodb_client
|
37
37
|
Exercism.s3_client
|
38
38
|
Exercism.ecr_client
|
39
|
+
Exercism.octokit_client
|
39
40
|
```
|
40
41
|
|
41
|
-
##
|
42
|
+
## Explanation
|
42
43
|
|
43
44
|
When terraform creates Exercism's infrastructure, it writes endpoints and DNS entries to DynamoDB.
|
44
45
|
This gem allows you to trivially retrieve that data.
|
@@ -27,119 +27,6 @@ unless ENV["EXERCISM_SKIP_S3"]
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
###########################################
|
31
|
-
# Setup local dynamodb tooling jobs table #
|
32
|
-
###########################################
|
33
|
-
[
|
34
|
-
Exercism.config.dynamodb_tooling_jobs_table,
|
35
|
-
Exercism.config.dynamodb_tooling_jobs_table + "-test"
|
36
|
-
].each do |table_name|
|
37
|
-
begin
|
38
|
-
Exercism.dynamodb_client.delete_table(
|
39
|
-
table_name: table_name
|
40
|
-
)
|
41
|
-
rescue Aws::DynamoDB::Errors::ResourceNotFoundException
|
42
|
-
end
|
43
|
-
puts "[x] #{table_name}"
|
44
|
-
|
45
|
-
Exercism.dynamodb_client.create_table(
|
46
|
-
table_name: table_name,
|
47
|
-
attribute_definitions: [
|
48
|
-
{
|
49
|
-
attribute_name: "id",
|
50
|
-
attribute_type: "S"
|
51
|
-
}
|
52
|
-
],
|
53
|
-
key_schema: [
|
54
|
-
{
|
55
|
-
attribute_name: "id",
|
56
|
-
key_type: "HASH"
|
57
|
-
}
|
58
|
-
],
|
59
|
-
provisioned_throughput: {
|
60
|
-
read_capacity_units: 1,
|
61
|
-
write_capacity_units: 1
|
62
|
-
}
|
63
|
-
)
|
64
|
-
|
65
|
-
Exercism.dynamodb_client.update_table(
|
66
|
-
table_name: table_name,
|
67
|
-
attribute_definitions: [
|
68
|
-
{
|
69
|
-
attribute_name: "job_status",
|
70
|
-
attribute_type: "S"
|
71
|
-
},
|
72
|
-
{
|
73
|
-
attribute_name: "created_at",
|
74
|
-
attribute_type: "N"
|
75
|
-
}
|
76
|
-
],
|
77
|
-
global_secondary_index_updates: [
|
78
|
-
{
|
79
|
-
create: {
|
80
|
-
index_name: "job_status", # required
|
81
|
-
key_schema: [ # required
|
82
|
-
{
|
83
|
-
attribute_name: "job_status", # required
|
84
|
-
key_type: "HASH" # required, accepts HASH, RANGE
|
85
|
-
},
|
86
|
-
{
|
87
|
-
attribute_name: "created_at", # required
|
88
|
-
key_type: "RANGE" # required, accepts HASH, RANGE
|
89
|
-
}
|
90
|
-
],
|
91
|
-
projection: { # required
|
92
|
-
projection_type: "KEYS_ONLY"
|
93
|
-
},
|
94
|
-
provisioned_throughput: {
|
95
|
-
read_capacity_units: 1, # required
|
96
|
-
write_capacity_units: 1 # required
|
97
|
-
}
|
98
|
-
}
|
99
|
-
}
|
100
|
-
]
|
101
|
-
)
|
102
|
-
|
103
|
-
Exercism.dynamodb_client.update_table(
|
104
|
-
table_name: table_name,
|
105
|
-
attribute_definitions: [
|
106
|
-
{
|
107
|
-
attribute_name: "submission_uuid",
|
108
|
-
attribute_type: "S"
|
109
|
-
},
|
110
|
-
{
|
111
|
-
attribute_name: "type",
|
112
|
-
attribute_type: "S"
|
113
|
-
}
|
114
|
-
],
|
115
|
-
global_secondary_index_updates: [
|
116
|
-
{
|
117
|
-
create: {
|
118
|
-
index_name: "submission_type", # required
|
119
|
-
key_schema: [ # required
|
120
|
-
{
|
121
|
-
attribute_name: "submission_uuid", # required
|
122
|
-
key_type: "HASH" # required, accepts HASH, RANGE
|
123
|
-
},
|
124
|
-
{
|
125
|
-
attribute_name: "type", # required
|
126
|
-
key_type: "RANGE" # required, accepts HASH, RANGE
|
127
|
-
}
|
128
|
-
],
|
129
|
-
projection: { # required
|
130
|
-
projection_type: "INCLUDE",
|
131
|
-
non_key_attributes: ["id", "job_status"]
|
132
|
-
},
|
133
|
-
provisioned_throughput: {
|
134
|
-
read_capacity_units: 1, # required
|
135
|
-
write_capacity_units: 1 # required
|
136
|
-
}
|
137
|
-
}
|
138
|
-
}
|
139
|
-
]
|
140
|
-
)
|
141
|
-
end
|
142
|
-
|
143
30
|
##############################################
|
144
31
|
# Setup local dynamodb language groups table #
|
145
32
|
##############################################
|
data/exercism_config.gemspec
CHANGED
data/lib/exercism-config.rb
CHANGED
@@ -16,6 +16,7 @@ require_relative 'exercism_config/retrieve_secrets'
|
|
16
16
|
require_relative 'exercism_config/version'
|
17
17
|
require_relative 'exercism/config'
|
18
18
|
require_relative 'exercism/secrets'
|
19
|
+
require_relative 'exercism/tooling_job'
|
19
20
|
|
20
21
|
module Exercism
|
21
22
|
class ConfigError < RuntimeError; end
|
@@ -32,6 +33,10 @@ module Exercism
|
|
32
33
|
@secrets ||= ExercismConfig::RetrieveSecrets.()
|
33
34
|
end
|
34
35
|
|
36
|
+
def self.redis_tooling_client
|
37
|
+
Redis.new(url: config.tooling_redis_url)
|
38
|
+
end
|
39
|
+
|
35
40
|
def self.dynamodb_client
|
36
41
|
Aws::DynamoDB::Client.new(ExercismConfig::GenerateAwsSettings.())
|
37
42
|
end
|
@@ -49,4 +54,19 @@ module Exercism
|
|
49
54
|
require 'aws-sdk-ecr'
|
50
55
|
Aws::ECR::Client.new(ExercismConfig::GenerateAwsSettings.())
|
51
56
|
end
|
57
|
+
|
58
|
+
def self.octokit_client
|
59
|
+
require 'octokit'
|
60
|
+
|
61
|
+
access_token = ENV.fetch(
|
62
|
+
"GITHUB_ACCESS_TOKEN",
|
63
|
+
self.secrets.github_access_token
|
64
|
+
)
|
65
|
+
|
66
|
+
@octokit_client ||= Octokit::Client.new(
|
67
|
+
access_token: access_token
|
68
|
+
).tap do |c|
|
69
|
+
c.auto_paginate = true
|
70
|
+
end
|
71
|
+
end
|
52
72
|
end
|
data/lib/exercism/config.rb
CHANGED
@@ -0,0 +1,151 @@
|
|
1
|
+
module Exercism
|
2
|
+
class ToolingJob
|
3
|
+
require 'aws-sdk-s3'
|
4
|
+
require 'redis'
|
5
|
+
|
6
|
+
extend Mandate::Memoize
|
7
|
+
|
8
|
+
def self.create!(type, submission_uuid, language, exercise, extra = {})
|
9
|
+
job_id = SecureRandom.uuid.tr('-', '')
|
10
|
+
data = extra.merge(
|
11
|
+
id: job_id,
|
12
|
+
submission_uuid: submission_uuid,
|
13
|
+
type: type,
|
14
|
+
language: language,
|
15
|
+
exercise: exercise,
|
16
|
+
created_at: Time.now.utc.to_i
|
17
|
+
)
|
18
|
+
|
19
|
+
redis = Exercism.redis_tooling_client
|
20
|
+
redis.multi do
|
21
|
+
redis.set(
|
22
|
+
"job:#{job_id}",
|
23
|
+
data.to_json
|
24
|
+
)
|
25
|
+
redis.rpush(key_for_queued, job_id)
|
26
|
+
redis.set("submission:#{submission_uuid}:#{type}", job_id)
|
27
|
+
end
|
28
|
+
new(job_id, data)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.find(id)
|
32
|
+
json = Exercism.redis_tooling_client.get("job:#{id}")
|
33
|
+
new(id, JSON.parse(json))
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.find_for_submission_uuid_and_type(submission_uuid, type)
|
37
|
+
redis = Exercism.redis_tooling_client
|
38
|
+
job_id = redis.get("submission:#{submission_uuid}:#{type}")
|
39
|
+
json = redis.get("job:#{job_id}")
|
40
|
+
new(job_id, JSON.parse(json))
|
41
|
+
end
|
42
|
+
|
43
|
+
attr_reader :id
|
44
|
+
|
45
|
+
def initialize(id, data)
|
46
|
+
@id = id
|
47
|
+
@data = data.freeze
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_h
|
51
|
+
data.to_h
|
52
|
+
end
|
53
|
+
|
54
|
+
def respond_to_missing?(meth)
|
55
|
+
data.key?(meth.to_s) || super
|
56
|
+
end
|
57
|
+
|
58
|
+
def method_missing(meth)
|
59
|
+
super unless respond_to_missing?(meth)
|
60
|
+
|
61
|
+
data[meth.to_s]
|
62
|
+
end
|
63
|
+
|
64
|
+
def locked!
|
65
|
+
redis = Exercism.redis_tooling_client
|
66
|
+
redis.multi do
|
67
|
+
redis.lrem(key_for_queued, 1, id)
|
68
|
+
redis.rpush(key_for_locked, id)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def executed!(status, output)
|
73
|
+
redis = Exercism.redis_tooling_client
|
74
|
+
redis.multi do
|
75
|
+
redis.lrem(key_for_queued, 1, id)
|
76
|
+
redis.lrem(key_for_locked, 1, id)
|
77
|
+
redis.rpush(key_for_executed, id)
|
78
|
+
|
79
|
+
redis.set(
|
80
|
+
"job:#{id}",
|
81
|
+
data.merge(
|
82
|
+
execution_status: status,
|
83
|
+
execution_output: output
|
84
|
+
).to_json
|
85
|
+
)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def processed!
|
90
|
+
redis = Exercism.redis_tooling_client
|
91
|
+
redis.multi do
|
92
|
+
redis.lrem(key_for_executed, 1, id)
|
93
|
+
redis.rpush(key_for_processed, id)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def cancelled!
|
98
|
+
redis = Exercism.redis_tooling_client
|
99
|
+
redis.multi do
|
100
|
+
redis.lrem(key_for_queued, 1, id)
|
101
|
+
redis.rpush(key_for_cancelled, id)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def ==(other)
|
106
|
+
id == other.id
|
107
|
+
end
|
108
|
+
|
109
|
+
def stderr
|
110
|
+
read_s3_file('stderr')
|
111
|
+
end
|
112
|
+
|
113
|
+
def stdout
|
114
|
+
read_s3_file('stdout')
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
attr_reader :data
|
119
|
+
|
120
|
+
def read_s3_file(name)
|
121
|
+
Exercism.s3_client.get_object(
|
122
|
+
bucket: s3_bucket_name,
|
123
|
+
key: "#{s3_folder}/#{name}"
|
124
|
+
).body.read
|
125
|
+
rescue StandardError
|
126
|
+
""
|
127
|
+
end
|
128
|
+
|
129
|
+
memoize
|
130
|
+
def s3_folder
|
131
|
+
"#{Exercism.env}/#{id}"
|
132
|
+
end
|
133
|
+
|
134
|
+
memoize
|
135
|
+
def s3_bucket_name
|
136
|
+
Exercism.config.aws_tooling_jobs_bucket
|
137
|
+
end
|
138
|
+
|
139
|
+
%w[queued locked executed processed cancelled].each do |key|
|
140
|
+
ToolingJob.singleton_class.class_eval do
|
141
|
+
define_method "key_for_#{key}" do
|
142
|
+
Exercism.env.production? ? key : "#{Exercism.env}:#{key}"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
define_method "key_for_#{key}" do
|
147
|
+
self.class.send("key_for_#{key}")
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
data/settings/ci.yml
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
anycable_redis_url: redis://127.0.0.1:6379/1
|
3
3
|
anycable_rpc_host: 127.0.0.1:50051
|
4
4
|
|
5
|
+
# Tooling
|
6
|
+
tooling_redis_url: redis://127.0.0.1:6379/3
|
7
|
+
|
5
8
|
# DynamoDB config
|
6
9
|
dynamodb_tooling_jobs_table: tooling_jobs
|
7
10
|
dynamodb_tooling_language_groups_table: tooling_language_groups
|
@@ -20,5 +23,12 @@ mysql_port: <%= ENV["MYSQL_PORT"] %>
|
|
20
23
|
aws_submissions_bucket: exercism-staging-submissions
|
21
24
|
aws_tooling_jobs_bucket: exercism-staging-tooling-jobs
|
22
25
|
|
26
|
+
# Hosts
|
27
|
+
website_icons_host: https://exercism-icons-staging.s3.eu-west-2.amazonaws.com
|
28
|
+
|
23
29
|
# Sidekiq Config
|
24
30
|
sidekiq_redis_url: redis://127.0.0.1:6379/2
|
31
|
+
|
32
|
+
# EFS Config
|
33
|
+
efs_submissions_mount_point: "/tmp/exercism/efs/submissions"
|
34
|
+
efs_repositories_mount_point: "/tmp/exercism/efs/repos"
|
data/settings/docker.yml
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
anycable_redis_url: redis://redis:6379/1
|
3
3
|
anycable_rpc_host: 0.0.0.0:50051
|
4
4
|
|
5
|
+
# Tooling
|
6
|
+
tooling_redis_url: redis://redis:6379/3
|
7
|
+
|
5
8
|
# DynamoDB config
|
6
9
|
dynamodb_tooling_jobs_table: tooling_jobs
|
7
10
|
dynamodb_tooling_language_groups_table: tooling_language_groups
|
@@ -20,5 +23,12 @@ mysql_port: 3306
|
|
20
23
|
aws_submissions_bucket: exercism-staging-submissions
|
21
24
|
aws_tooling_jobs_bucket: exercism-staging-tooling-jobs
|
22
25
|
|
26
|
+
# Hosts
|
27
|
+
website_icons_host: https://exercism-icons-staging.s3.eu-west-2.amazonaws.com
|
28
|
+
|
23
29
|
# Sidekiq Config
|
24
30
|
sidekiq_redis_url: redis://redis:6379/2
|
31
|
+
|
32
|
+
# EFS Config
|
33
|
+
efs_submissions_mount_point: "/tmp/exercism/efs/submissions"
|
34
|
+
efs_repositories_mount_point: "/tmp/exercism/efs/repos"
|
data/settings/local.yml
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
anycable_redis_url: redis://127.0.0.1:6379/1
|
3
3
|
anycable_rpc_host: 127.0.0.1:50051
|
4
4
|
|
5
|
+
# Tooling
|
6
|
+
tooling_redis_url: redis://127.0.0.1:6379/3
|
7
|
+
|
5
8
|
# DynamoDB config
|
6
9
|
dynamodb_tooling_jobs_table: tooling_jobs
|
7
10
|
dynamodb_tooling_language_groups_table: tooling_language_groups
|
@@ -20,5 +23,18 @@ mysql_port: null
|
|
20
23
|
aws_submissions_bucket: exercism-staging-submissions
|
21
24
|
aws_tooling_jobs_bucket: exercism-staging-tooling-jobs
|
22
25
|
|
26
|
+
# Hosts
|
27
|
+
website_icons_host: https://exercism-icons-staging.s3.eu-west-2.amazonaws.com
|
28
|
+
|
23
29
|
# Sidekiq Config
|
24
30
|
sidekiq_redis_url: redis://127.0.0.1:6379/2
|
31
|
+
|
32
|
+
# EFS Config
|
33
|
+
efs_submissions_mount_point: "/tmp/exercism/efs/submissions"
|
34
|
+
efs_repositories_mount_point: "/tmp/exercism/efs/repos"
|
35
|
+
|
36
|
+
# Extra things not used in development, but here
|
37
|
+
# so that this file can provide a reference
|
38
|
+
website_assets_host:
|
39
|
+
aws_attachments_bucket:
|
40
|
+
aws_attachments_region:
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: exercism-config
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.65.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Walker
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-05-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-dynamodb
|
@@ -150,6 +150,20 @@ dependencies:
|
|
150
150
|
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: redis
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
153
167
|
description:
|
154
168
|
email:
|
155
169
|
- jez.walker@gmail.com
|
@@ -177,6 +191,7 @@ files:
|
|
177
191
|
- lib/exercism-config.rb
|
178
192
|
- lib/exercism/config.rb
|
179
193
|
- lib/exercism/secrets.rb
|
194
|
+
- lib/exercism/tooling_job.rb
|
180
195
|
- lib/exercism_config/determine_environment.rb
|
181
196
|
- lib/exercism_config/environment.rb
|
182
197
|
- lib/exercism_config/generate_aws_settings.rb
|