Compare commits
952 Commits
deploy.201
...
master
Author | SHA1 | Date | |
---|---|---|---|
![]() |
542592ae41 | ||
![]() |
c2c1952d40 | ||
![]() |
ca80c7f0a2 | ||
![]() |
a9f84c27b0 | ||
![]() |
65aece922c | ||
![]() |
17ccc22fbe | ||
![]() |
51575bdb89 | ||
![]() |
b3e8b9d43b | ||
![]() |
ba6b5b7cba | ||
![]() |
8afaeb10c0 | ||
![]() |
c7161cec81 | ||
![]() |
8a14ef827f | ||
![]() |
32503b0731 | ||
![]() |
178122e247 | ||
![]() |
7655d0edd2 | ||
![]() |
885ae009f4 | ||
![]() |
614b1f5338 | ||
![]() |
8655579a94 | ||
![]() |
77e47bc41a | ||
![]() |
779b6a569e | ||
![]() |
abe7b13605 | ||
![]() |
0dc7e2743c | ||
![]() |
d42362eacc | ||
![]() |
1788e0c0fb | ||
![]() |
20d4df8af3 | ||
![]() |
d41ddd7171 | ||
![]() |
6ca063cf3d | ||
![]() |
f787a96b96 | ||
![]() |
d0a143d76a | ||
![]() |
cdce95a508 | ||
![]() |
0f2b1edae1 | ||
![]() |
f09e9931b2 | ||
![]() |
75bd65e56c | ||
![]() |
f4cb24c4b4 | ||
![]() |
4888c2c905 | ||
![]() |
edf889b55f | ||
![]() |
0dc1009ab4 | ||
![]() |
255640fd4f | ||
![]() |
bcf08e0e7e | ||
![]() |
89eea1682f | ||
![]() |
9e1c6933f5 | ||
![]() |
3f97b40914 | ||
![]() |
90e5d968ea | ||
![]() |
7d70f161a1 | ||
![]() |
7f3fb70ec7 | ||
![]() |
175e266a6d | ||
![]() |
e037127a9c | ||
![]() |
5293919f3a | ||
![]() |
c6a1eda572 | ||
![]() |
cb89cae39f | ||
![]() |
bcbf0abf60 | ||
![]() |
9e2fff6e0a | ||
![]() |
5dd513f79b | ||
![]() |
9b5893b07c | ||
![]() |
8bd4d7db5e | ||
![]() |
4254b181d4 | ||
![]() |
8eb9811b30 | ||
![]() |
93cfcadeef | ||
![]() |
9e61d5e636 | ||
![]() |
c112c56664 | ||
![]() |
3a1b1a591f | ||
![]() |
72be42b88f | ||
![]() |
291fea3e07 | ||
![]() |
1733ea69d5 | ||
![]() |
543998feea | ||
![]() |
e31976974c | ||
![]() |
c90991e10a | ||
![]() |
c00cdbaff7 | ||
![]() |
5e798aca6f | ||
![]() |
7107f4378c | ||
![]() |
1e04b52f5f | ||
![]() |
20be47698a | ||
![]() |
185067265c | ||
![]() |
27dbe9a75a | ||
![]() |
cafe40a4c3 | ||
![]() |
e5492f77ce | ||
![]() |
2df85a5068 | ||
![]() |
22a26580d9 | ||
![]() |
b471b92b60 | ||
![]() |
89c96ecb95 | ||
![]() |
0647dcdcb2 | ||
![]() |
11594487fb | ||
![]() |
476e944c55 | ||
![]() |
65f1a29d86 | ||
![]() |
e9b3ed308a | ||
![]() |
bfd44e1d77 | ||
![]() |
155767ea37 | ||
![]() |
70adc93a8f | ||
![]() |
9ab4111f33 | ||
![]() |
0ee949a846 | ||
![]() |
8c512677f1 | ||
![]() |
510fb8b146 | ||
![]() |
75ef3a6367 | ||
![]() |
a45d53f73c | ||
![]() |
652439226a | ||
![]() |
b31301ac1f | ||
![]() |
48e4a2c589 | ||
![]() |
58cd17158c | ||
![]() |
01893ba62b | ||
![]() |
42b1661107 | ||
![]() |
16968f445f | ||
![]() |
c10145cc93 | ||
![]() |
35ae19c3a0 | ||
![]() |
8cdbca925b | ||
![]() |
2783a69f89 | ||
![]() |
40bff028f3 | ||
![]() |
8b7a589018 | ||
![]() |
87a069863a | ||
![]() |
14ea592cd7 | ||
![]() |
54e9d2fd06 | ||
![]() |
f544f3b15a | ||
![]() |
a5480fb097 | ||
![]() |
b234ad73be | ||
![]() |
2ab8af6659 | ||
![]() |
564e95be6b | ||
![]() |
1a36fc6195 | ||
![]() |
f8b8ef54a9 | ||
![]() |
3fb7c35286 | ||
![]() |
f63bb1c6a2 | ||
![]() |
f1d7305e9d | ||
![]() |
b94d9c8637 | ||
![]() |
f7f6478fa4 | ||
![]() |
21f445ad64 | ||
![]() |
1ec8dba7e4 | ||
![]() |
1d7bc10ed9 | ||
![]() |
ac7e610510 | ||
![]() |
db193cb541 | ||
![]() |
ff7d1dbfdd | ||
![]() |
237f270708 | ||
![]() |
50b78a1458 | ||
![]() |
79c14d697e | ||
![]() |
d84d3983b8 | ||
![]() |
a210cf8661 | ||
![]() |
0d90c21dbd | ||
![]() |
7e8b65a311 | ||
![]() |
e6d7607916 | ||
![]() |
c1de919852 | ||
![]() |
7d52b06533 | ||
![]() |
829366a554 | ||
![]() |
4b14f17cc5 | ||
![]() |
f5bc526f25 | ||
![]() |
1a07e199b5 | ||
![]() |
91e9fcebf7 | ||
![]() |
871b915515 | ||
![]() |
77dcdaa482 | ||
![]() |
09806a5f93 | ||
![]() |
b5fe8f1884 | ||
![]() |
b9d65ff30f | ||
![]() |
34fbfc2ccf | ||
![]() |
bed317b109 | ||
![]() |
0156671fc8 | ||
![]() |
1f56dcc645 | ||
![]() |
14625ff7cb | ||
![]() |
69f0a9d33e | ||
![]() |
0e5aa2fb7a | ||
![]() |
bfb68bf931 | ||
![]() |
69cc2eef7d | ||
![]() |
16a7da54c2 | ||
![]() |
0aeec35935 | ||
![]() |
769ae71076 | ||
![]() |
32dd8d9f93 | ||
![]() |
fcb0e7cde4 | ||
![]() |
88d9000042 | ||
![]() |
81e93ca710 | ||
![]() |
00fb01bd7a | ||
![]() |
cae6da540f | ||
![]() |
026dc4cb98 | ||
![]() |
cf5ea374d4 | ||
![]() |
dc176e0c0e | ||
![]() |
25f74defe5 | ||
![]() |
7250656de0 | ||
![]() |
6603990fe4 | ||
![]() |
da4c7f26e6 | ||
![]() |
060dd8aced | ||
![]() |
84ebb6b24e | ||
![]() |
734a7b9566 | ||
![]() |
eb78d9df30 | ||
![]() |
fb0493a33c | ||
![]() |
04cd5bea24 | ||
![]() |
c6f6dd5f5a | ||
![]() |
0f1e697abd | ||
![]() |
a6658fa4d3 | ||
![]() |
a26c188822 | ||
![]() |
51c6c8f58f | ||
![]() |
81d8c64e98 | ||
![]() |
4e858e3949 | ||
![]() |
bf20506e09 | ||
![]() |
41c274b222 | ||
![]() |
3cfac6a5c1 | ||
![]() |
3508df01a9 | ||
![]() |
c0e57cc890 | ||
![]() |
4155c8ebcd | ||
![]() |
5949429f75 | ||
![]() |
a2d1322b60 | ||
![]() |
bb7260bc9e | ||
![]() |
91ca0efe03 | ||
![]() |
b36a6f8358 | ||
![]() |
06de527c63 | ||
![]() |
8f9d5e41b7 | ||
![]() |
2624bd9e72 | ||
![]() |
56a59e4cc3 | ||
![]() |
c4e58c3e63 | ||
![]() |
341adbae21 | ||
![]() |
feb4bcd90f | ||
![]() |
0077b6414a | ||
![]() |
489c404bbb | ||
![]() |
e467fa3e6d | ||
![]() |
ce071ad728 | ||
![]() |
5776e13385 | ||
![]() |
62f0bf7081 | ||
![]() |
1ca54b361f | ||
![]() |
4b6c177311 | ||
![]() |
7691d04de0 | ||
![]() |
a02995e357 | ||
![]() |
7c3c6bd1a9 | ||
![]() |
e097c8889e | ||
![]() |
0f2c7e0307 | ||
![]() |
cecc501255 | ||
![]() |
5a8c1e63c4 | ||
![]() |
692308837d | ||
![]() |
3b490b58cb | ||
![]() |
e77be8210f | ||
![]() |
9ed43941fd | ||
![]() |
e1f7921223 | ||
![]() |
ae133e649a | ||
![]() |
3b6ab6fb71 | ||
![]() |
75460b2427 | ||
![]() |
777e42374c | ||
![]() |
b67c226515 | ||
![]() |
5fee54b91b | ||
![]() |
1c99216e23 | ||
![]() |
eb0eab5967 | ||
![]() |
daf534edb7 | ||
![]() |
fba9a87c39 | ||
![]() |
05f926b0ec | ||
![]() |
6656b5d0aa | ||
![]() |
b649bb5a0f | ||
![]() |
24865ee322 | ||
![]() |
686e3c9baf | ||
![]() |
7317d6b265 | ||
![]() |
3a58979e43 | ||
![]() |
b1de9d569c | ||
![]() |
dbe0a75a22 | ||
![]() |
8b9df97e3f | ||
![]() |
9df4dc02cf | ||
![]() |
7200744879 | ||
![]() |
92dd9a5ce0 | ||
![]() |
bec9f35e69 | ||
![]() |
2303db9f4f | ||
![]() |
1c9212ef08 | ||
![]() |
794e2d70af | ||
![]() |
0038197aab | ||
![]() |
574dfab772 | ||
![]() |
8c6477c247 | ||
![]() |
ace3e588ea | ||
![]() |
a8b70f51f3 | ||
![]() |
21c714ae97 | ||
![]() |
d7d8e3bbe3 | ||
![]() |
2ded8ac2be | ||
![]() |
8655fd19ce | ||
![]() |
6de524d84c | ||
![]() |
0e43360f1d | ||
![]() |
799d757625 | ||
![]() |
504be84f27 | ||
![]() |
68daabafa0 | ||
![]() |
00bae7a945 | ||
![]() |
29f80ab31b | ||
![]() |
ef7811ead9 | ||
![]() |
c3e0d6d6bb | ||
![]() |
428422d569 | ||
![]() |
fa50bd13de | ||
![]() |
1863f5bd0c | ||
![]() |
efb9d899b2 | ||
![]() |
6e51368525 | ||
![]() |
e62ba7722e | ||
![]() |
276a61759d | ||
![]() |
1d3a2ebb67 | ||
![]() |
3c253bb88c | ||
![]() |
2b37d90ffb | ||
![]() |
9bd145856b | ||
![]() |
9bbfb7ec97 | ||
![]() |
28884f9931 | ||
![]() |
e876a83d86 | ||
![]() |
2a66505aca | ||
![]() |
1615928c68 | ||
![]() |
5cade805e0 | ||
![]() |
659dc4d992 | ||
![]() |
754101e9af | ||
![]() |
654185538f | ||
![]() |
13d9c97501 | ||
![]() |
52bebad05c | ||
![]() |
c9b93982c9 | ||
![]() |
9d386efa4c | ||
![]() |
168bc39d2a | ||
![]() |
7f437f9d27 | ||
![]() |
ea838dd246 | ||
![]() |
0458482fdf | ||
![]() |
d21fc58955 | ||
![]() |
4ec8e1acdc | ||
![]() |
c6ddffc85a | ||
![]() |
732e8a956d | ||
![]() |
f186c16669 | ||
![]() |
0593c55ef6 | ||
![]() |
7b5c11fca6 | ||
![]() |
63bef443e8 | ||
![]() |
30d73782c8 | ||
![]() |
379a63bf00 | ||
![]() |
ec217a58f1 | ||
![]() |
506e0f0f7a | ||
![]() |
ec62a5b918 | ||
![]() |
13aa741e57 | ||
![]() |
78f36320a7 | ||
![]() |
00aaf32b1e | ||
![]() |
93bc69dc9d | ||
![]() |
7e7f1b212b | ||
![]() |
27f18d77ac | ||
![]() |
a67f6bb2ea | ||
![]() |
55f8378940 | ||
![]() |
866fd2a617 | ||
![]() |
d522072705 | ||
![]() |
c22998fdcf | ||
![]() |
6b7526dd7e | ||
![]() |
845f02d8d9 | ||
![]() |
0b2585de45 | ||
![]() |
72c204883f | ||
![]() |
1b9b422753 | ||
![]() |
c6d9e5ad7d | ||
![]() |
efe26b03a1 | ||
![]() |
dc4d6f0208 | ||
![]() |
482f037438 | ||
![]() |
357257b654 | ||
![]() |
1f0d26a01c | ||
![]() |
ce1ba54f77 | ||
![]() |
03e992885e | ||
![]() |
228b594237 | ||
![]() |
11ceaed333 | ||
![]() |
679bbd7901 | ||
![]() |
4556130acb | ||
![]() |
407d2abea1 | ||
![]() |
7922ca8e84 | ||
![]() |
e4b1562039 | ||
![]() |
a37acda0a0 | ||
![]() |
5fc096f68b | ||
![]() |
9f9c5bf789 | ||
![]() |
855997aba8 | ||
![]() |
cab8534b4a | ||
![]() |
7f4d67ea8d | ||
![]() |
0e8fe08f7c | ||
![]() |
a522607673 | ||
![]() |
31f6b5793a | ||
![]() |
c49819ca52 | ||
![]() |
bc42810a53 | ||
![]() |
6e3577401e | ||
![]() |
24b2abdfd0 | ||
![]() |
f51cf1a1d1 | ||
![]() |
d6c0621d71 | ||
![]() |
49a6bb5d26 | ||
![]() |
2f870e6826 | ||
![]() |
7ca67875b4 | ||
![]() |
d1848ba6f9 | ||
![]() |
1dd47df6bf | ||
![]() |
9734e7133f | ||
![]() |
a466f0c819 | ||
![]() |
f2d3758e09 | ||
![]() |
75937e45ee | ||
![]() |
e183401888 | ||
![]() |
f1b3101ac7 | ||
![]() |
bcdd15f4cf | ||
![]() |
aa211be12a | ||
![]() |
30b8f2d772 | ||
![]() |
55287b23df | ||
![]() |
7a95dabe95 | ||
![]() |
4db60de568 | ||
![]() |
2db04f068c | ||
![]() |
1d6ed1e364 | ||
![]() |
dd82c14f5b | ||
![]() |
f8bee8f801 | ||
![]() |
40c4c0d7ef | ||
![]() |
69df412aa1 | ||
![]() |
8085710646 | ||
![]() |
5af88d005c | ||
![]() |
1dd8b6aec5 | ||
![]() |
1af7cd5f45 | ||
![]() |
1e69683c3c | ||
![]() |
ba0e43c75a | ||
![]() |
82b8512f41 | ||
![]() |
ca82725e5e | ||
![]() |
569a1d3967 | ||
![]() |
92ec0e352a | ||
![]() |
9235f1057d | ||
![]() |
71813bf92a | ||
![]() |
b552544d19 | ||
![]() |
48880ad184 | ||
![]() |
197120a9eb | ||
![]() |
11ef8d1a61 | ||
![]() |
c037ec7aa3 | ||
![]() |
462a3618e1 | ||
![]() |
fe76d38230 | ||
![]() |
354fa83e42 | ||
![]() |
2de73fd974 | ||
![]() |
6b145e6f06 | ||
![]() |
7215151403 | ||
![]() |
ac0012b0a2 | ||
![]() |
f940bffe3f | ||
![]() |
69852d18b3 | ||
![]() |
8a050a468c | ||
![]() |
5294f1dab2 | ||
![]() |
f0dcf270bc | ||
![]() |
6aaa25a099 | ||
![]() |
f2c96b3eb5 | ||
![]() |
5682502cba | ||
![]() |
8ca1c4d824 | ||
![]() |
b68c7a33b0 | ||
![]() |
55621067cc | ||
![]() |
7e438be4cf | ||
![]() |
4462613c46 | ||
![]() |
06cf863fec | ||
![]() |
e1fefaf456 | ||
![]() |
ac400906a1 | ||
![]() |
da0576d995 | ||
![]() |
07dd57845b | ||
![]() |
643ca01ee5 | ||
![]() |
156a6ebb98 | ||
![]() |
74b43d5e89 | ||
![]() |
087788757f | ||
![]() |
5663410c45 | ||
![]() |
5cb5fdb8d6 | ||
![]() |
dd7e74950d | ||
![]() |
6c839aebec | ||
![]() |
3a97ac8bfa | ||
![]() |
f512975e6a | ||
![]() |
b784eaee82 | ||
![]() |
3182513798 | ||
![]() |
7a7e957b80 | ||
![]() |
189bf99b18 | ||
![]() |
593c6edaa6 | ||
![]() |
c0e01c46d2 | ||
![]() |
e99fd09e2d | ||
![]() |
41ef072a94 | ||
![]() |
6324bbeef8 | ||
![]() |
a45178c67d | ||
![]() |
aaed416238 | ||
![]() |
73f724c58c | ||
![]() |
d944fe347a | ||
![]() |
ba142b84c7 | ||
![]() |
05e860dd35 | ||
![]() |
56ea1d6663 | ||
![]() |
5b25683ce8 | ||
![]() |
ca09547452 | ||
![]() |
d1e07f10f0 | ||
![]() |
fa8520eb25 | ||
![]() |
b6b1d12f48 | ||
![]() |
82b95440b2 | ||
![]() |
89487c09ca | ||
![]() |
80cb945557 | ||
![]() |
e6d39c2a52 | ||
![]() |
1ee5421d3f | ||
![]() |
2196acb36d | ||
![]() |
8490e9f9ce | ||
![]() |
022089adc8 | ||
![]() |
f319dfbf65 | ||
![]() |
fa5f65606e | ||
![]() |
0448427136 | ||
![]() |
ab1bfe0aeb | ||
![]() |
ca5820e2e3 | ||
![]() |
54572a5ded | ||
![]() |
2b89f7ac30 | ||
![]() |
77ec852be6 | ||
![]() |
ec8ef98c0d | ||
![]() |
64f97a89d2 | ||
![]() |
6ab0ec3c3a | ||
![]() |
9744f59fe2 | ||
![]() |
14b7159109 | ||
![]() |
c1d6441c7e | ||
![]() |
e283140d02 | ||
![]() |
25bd6b88b7 | ||
![]() |
4d98ccafd6 | ||
![]() |
14ec02da79 | ||
![]() |
e2e222ab7c | ||
![]() |
179b166de4 | ||
![]() |
1fb526de7e | ||
![]() |
345921a98b | ||
![]() |
15e3b84dca | ||
![]() |
84cfacadb6 | ||
![]() |
16db162696 | ||
![]() |
c13cabfbf3 | ||
![]() |
6c5c483166 | ||
![]() |
5f32123891 | ||
![]() |
797ca9f9fa | ||
![]() |
a66191c682 | ||
![]() |
416fcf2d4b | ||
![]() |
8c3c4fe935 | ||
![]() |
693e293909 | ||
![]() |
277562e51c | ||
![]() |
079cec3467 | ||
![]() |
8d1cd15ee2 | ||
![]() |
54e2ca0300 | ||
![]() |
b16ae846ad | ||
![]() |
979201794f | ||
![]() |
cafb078c10 | ||
![]() |
c085354706 | ||
![]() |
172156da59 | ||
![]() |
6f16091207 | ||
![]() |
b82ca5e438 | ||
![]() |
6e8606c01e | ||
![]() |
66e63897a3 | ||
![]() |
6b230828e6 | ||
![]() |
8d98f39e79 | ||
![]() |
5e94e7436b | ||
![]() |
5353ed027e | ||
![]() |
4833f41732 | ||
![]() |
efab4be6de | ||
![]() |
a830bfe8ad | ||
![]() |
8a6f4066ae | ||
![]() |
3fa9c09c0c | ||
![]() |
0d1dbaadd7 | ||
![]() |
be01b36f05 | ||
![]() |
6fb0f7b6ce | ||
![]() |
98a75e5931 | ||
![]() |
d75daab82f | ||
![]() |
64478d50d1 | ||
![]() |
24b0af35e9 | ||
![]() |
05d2e4767e | ||
![]() |
00db637788 | ||
![]() |
67d1d09569 | ||
![]() |
2c60a85fdb | ||
![]() |
bf1714c437 | ||
![]() |
598ca6c2ca | ||
![]() |
2d2e7aa528 | ||
![]() |
4704992a18 | ||
![]() |
b572a1a50e | ||
![]() |
da33cff0eb | ||
![]() |
9b24312445 | ||
![]() |
2566a7761c | ||
![]() |
43a2806b3b | ||
![]() |
3f11b08a25 | ||
![]() |
1640c444de | ||
![]() |
e9356970f8 | ||
![]() |
00e15de083 | ||
![]() |
3637061b76 | ||
![]() |
7a5f477a0a | ||
![]() |
ffcf8985c0 | ||
![]() |
587ed37395 | ||
![]() |
0632c3d08f | ||
![]() |
68ba4b9fce | ||
![]() |
2d00e16962 | ||
![]() |
0920041375 | ||
![]() |
9588f816b0 | ||
![]() |
b45b3fadf7 | ||
![]() |
cf20650d39 | ||
![]() |
089deeb217 | ||
![]() |
01a86c1dd5 | ||
![]() |
43480752fa | ||
![]() |
e4aec173ee | ||
![]() |
24cedb57b1 | ||
![]() |
bddd9952a7 | ||
![]() |
6ddb826f1d | ||
![]() |
759fdf203b | ||
![]() |
dff78176cc | ||
![]() |
785ec6c784 | ||
![]() |
bbba45990d | ||
![]() |
82f280f5d3 | ||
![]() |
8132258b2c | ||
![]() |
ff68df9fb5 | ||
![]() |
8fc9ade6de | ||
![]() |
553700d402 | ||
![]() |
94c2edfbe1 | ||
![]() |
e9533fb056 | ||
![]() |
13e6959b21 | ||
![]() |
d42e337996 | ||
![]() |
a638aee0ff | ||
![]() |
a7fa8f6a6f | ||
![]() |
98080beeaf | ||
![]() |
16817ff98e | ||
![]() |
28fde8333a | ||
![]() |
a3e83659f7 | ||
![]() |
cc14ebac48 | ||
![]() |
d587b766f3 | ||
![]() |
dcc92491f7 | ||
![]() |
b5c061b239 | ||
![]() |
e1aee4a3b0 | ||
![]() |
7be5bf6fec | ||
![]() |
0ecbd8b237 | ||
![]() |
a4bce14a73 | ||
![]() |
83b6bed184 | ||
![]() |
f602ce0989 | ||
![]() |
6acf267a04 | ||
![]() |
7304606687 | ||
![]() |
619ff93057 | ||
![]() |
f7cd49f194 | ||
![]() |
dece76ce5b | ||
![]() |
b6186890c4 | ||
![]() |
06b5e0af15 | ||
![]() |
c0d562cb7d | ||
![]() |
50e198beee | ||
![]() |
54ffac9916 | ||
![]() |
221b309653 | ||
![]() |
620e38a2a0 | ||
![]() |
dfdfe651af | ||
![]() |
5d6b25a2b4 | ||
![]() |
01591cefa5 | ||
![]() |
afb6fe286b | ||
![]() |
24d5efda95 | ||
![]() |
2b8d7e420b | ||
![]() |
8d3acfe9bb | ||
![]() |
086932df11 | ||
![]() |
2974dccd3b | ||
![]() |
cf5915a06b | ||
![]() |
c2168d62f1 | ||
![]() |
937cc0267a | ||
![]() |
baa1881bf7 | ||
![]() |
d3b13e8d7c | ||
![]() |
af3087446c | ||
![]() |
7eb2617e48 | ||
![]() |
dbea2f3760 | ||
![]() |
81e11da856 | ||
![]() |
02f5035100 | ||
![]() |
4095090992 | ||
![]() |
a31a6cb92b | ||
![]() |
9793010e28 | ||
![]() |
77aabcb78f | ||
![]() |
fb483689e9 | ||
![]() |
4a3357a488 | ||
![]() |
8f0b35a0f1 | ||
![]() |
efb91d0a38 | ||
![]() |
02d3fad23f | ||
![]() |
b138fbcdeb | ||
![]() |
8f5a34c7b6 | ||
![]() |
4f9cb29775 | ||
![]() |
28ff2f6848 | ||
![]() |
95ad9a6b56 | ||
![]() |
c20f99d210 | ||
![]() |
0f4a29c31c | ||
![]() |
2420784a87 | ||
![]() |
18ea7853bf | ||
![]() |
f356beaccf | ||
![]() |
16687f16d7 | ||
![]() |
714e40beca | ||
![]() |
c96e8e2ff1 | ||
![]() |
75449baacd | ||
![]() |
aca632ed15 | ||
![]() |
480aac2171 | ||
![]() |
0a91a69d0d | ||
![]() |
e8ab7c0be6 | ||
![]() |
b1408583dd | ||
![]() |
0e1b266e9b | ||
![]() |
b3eb2f3398 | ||
![]() |
f5f4b3b0b1 | ||
![]() |
a2a4737099 | ||
![]() |
c6556977fa | ||
![]() |
d1dd965b32 | ||
![]() |
c08f8243fb | ||
![]() |
208dfb9a93 | ||
![]() |
ec37deb17c | ||
![]() |
5295d0c3ee | ||
![]() |
772e797aae | ||
![]() |
046a63b60a | ||
![]() |
a6327ec4d2 | ||
![]() |
9c9aa3334c | ||
![]() |
4035b22bf6 | ||
![]() |
426a68f567 | ||
![]() |
26b1d85d43 | ||
![]() |
b923b21252 | ||
![]() |
b4fa2220a7 | ||
![]() |
59d3090da6 | ||
![]() |
0339a4f3e6 | ||
![]() |
57f31c6573 | ||
![]() |
df3ec4084a | ||
![]() |
2e590585fe | ||
![]() |
2c8db7aa61 | ||
![]() |
f02c9e0a02 | ||
![]() |
96f3e554ee | ||
![]() |
245edc5f55 | ||
![]() |
e45d6c9dfe | ||
![]() |
64dadb7549 | ||
![]() |
bce9ea5b46 | ||
![]() |
dc248302ab | ||
![]() |
588465766f | ||
![]() |
3d171394a6 | ||
![]() |
083355227f | ||
![]() |
4a23a1e0c5 | ||
![]() |
7237ad766e | ||
![]() |
a51ee4cb99 | ||
![]() |
9bcf83bc09 | ||
![]() |
10c05434e8 | ||
![]() |
615499489a | ||
![]() |
58b388db69 | ||
![]() |
c37e01c911 | ||
![]() |
4a11c22a74 | ||
![]() |
099d10f466 | ||
![]() |
0fc7c35e0c | ||
![]() |
03c982a45a | ||
![]() |
df8f2537cc | ||
![]() |
571af14067 | ||
![]() |
2ebfa1d85b | ||
![]() |
8a7ff5c6b8 | ||
![]() |
3904d9e362 | ||
![]() |
aa222ad6b2 | ||
![]() |
9edb598884 | ||
![]() |
949a876550 | ||
![]() |
1d783129ce | ||
![]() |
1a5788e2a1 | ||
![]() |
9461807834 | ||
![]() |
cf416e6001 | ||
![]() |
202377181e | ||
![]() |
783e9af5b9 | ||
![]() |
ac94487d7c | ||
![]() |
5dc0e62bf6 | ||
![]() |
4697deae26 | ||
![]() |
4b76e8f658 | ||
![]() |
6f0a42abee | ||
![]() |
16c871d740 | ||
![]() |
815d9e6e9b | ||
![]() |
0890d0b76a | ||
![]() |
3e112294cb | ||
![]() |
aadd29574c | ||
![]() |
4ed55a804e | ||
![]() |
4cc50009aa | ||
![]() |
9bdc7b496e | ||
![]() |
860edf37bf | ||
![]() |
2d0bb58e35 | ||
![]() |
d7c9a367e9 | ||
![]() |
06486c57a5 | ||
![]() |
0eb564388c | ||
![]() |
1c4579008b | ||
![]() |
e03f79513a | ||
![]() |
6cc0e6139f | ||
![]() |
509c29b33e | ||
![]() |
33d31131c1 | ||
![]() |
0249140dc8 | ||
![]() |
1bec0c1332 | ||
![]() |
e218b13073 | ||
![]() |
148e2acefe | ||
![]() |
716bd1f8e6 | ||
![]() |
3dc1c5b486 | ||
![]() |
154be5c38d | ||
![]() |
36d361b7af | ||
![]() |
fd03316de7 | ||
![]() |
b6ffb8bdf8 | ||
![]() |
d8e24bf52f | ||
![]() |
e3de9a4f07 | ||
![]() |
a2deeb1d96 | ||
![]() |
38b73f53cb | ||
![]() |
f3b8258b53 | ||
![]() |
5c6e705012 | ||
![]() |
b73a5604d0 | ||
![]() |
2bc72d8b9b | ||
![]() |
d99c3c8c54 | ||
![]() |
c6cc6d1b96 | ||
![]() |
2e110bc455 | ||
![]() |
faf60a5f7f | ||
![]() |
faabb0f727 | ||
![]() |
6187c2a9c1 | ||
![]() |
4e2d33995a | ||
![]() |
ab979e2356 | ||
![]() |
866ed28641 | ||
![]() |
af7fdec340 | ||
![]() |
6821cec524 | ||
![]() |
986ae0ef97 | ||
![]() |
aef8672cba | ||
![]() |
9f2b880f83 | ||
![]() |
e40e6d3fe9 | ||
![]() |
c372b07344 | ||
![]() |
e8769dddc5 | ||
![]() |
5e40f33fc1 | ||
![]() |
e478c621f2 | ||
![]() |
dc0da3645a | ||
![]() |
9303a24595 | ||
![]() |
b59fa6cd94 | ||
![]() |
af977ca677 | ||
![]() |
3e0423aae3 | ||
![]() |
fb4bedbb6b | ||
![]() |
950b922e63 | ||
![]() |
4a0932df1e | ||
![]() |
1e6d4738e3 | ||
![]() |
dc7ced1c7f | ||
![]() |
907591e001 | ||
![]() |
28c6e04eb8 | ||
![]() |
1640c33517 | ||
![]() |
bd61d1e58e | ||
![]() |
fba1d65e76 | ||
![]() |
0705a61808 | ||
![]() |
8645338306 | ||
![]() |
2c5ad649f5 | ||
![]() |
9d7a01e60c | ||
![]() |
2e72233213 | ||
![]() |
f44b374d79 | ||
![]() |
beaa4b7e17 | ||
![]() |
3242189259 | ||
![]() |
2891dd640a | ||
![]() |
702b539ddf | ||
![]() |
f57f62ba75 | ||
![]() |
070be827df | ||
![]() |
211637e247 | ||
![]() |
210f368de4 | ||
![]() |
288d614977 | ||
![]() |
18e5c22fd7 | ||
![]() |
d99d80ac98 | ||
![]() |
8e8e139391 | ||
![]() |
e80dfadf5c | ||
![]() |
8e6dbf9319 | ||
![]() |
5893241ca5 | ||
![]() |
64673eb971 | ||
![]() |
1a3d42da21 | ||
![]() |
98bcc9e530 | ||
![]() |
6b0850813c | ||
![]() |
e3d56ecadb | ||
![]() |
2610c03801 | ||
![]() |
ee03ebfbe5 | ||
![]() |
51bcdec77a | ||
![]() |
d207f1c31c | ||
![]() |
720d8aa284 | ||
![]() |
90812293fe | ||
![]() |
995ee333a8 | ||
![]() |
d8ad047dc8 | ||
![]() |
11f5f2cb66 | ||
![]() |
517b3b60ef | ||
![]() |
96a79be68c | ||
![]() |
a7111ba949 | ||
![]() |
09df061268 | ||
![]() |
b4a3bdeb0e | ||
![]() |
462b2aed0d | ||
![]() |
4eb89ab141 | ||
![]() |
73ec1d496e | ||
![]() |
cc346ce165 | ||
![]() |
cbc5329b3d | ||
![]() |
34bff32c3d | ||
![]() |
8057dc7ab9 | ||
![]() |
456f52405e | ||
![]() |
b3f47d3856 | ||
![]() |
ac522d6fdd | ||
![]() |
8ef0a2d8e5 | ||
![]() |
28e3e52b3e | ||
![]() |
5ef17e7da0 | ||
![]() |
e9d11056c0 | ||
![]() |
f7634f0f39 | ||
![]() |
fe9a6536d7 | ||
![]() |
18a90c2561 | ||
![]() |
69a4a0a735 | ||
![]() |
120cbadf85 | ||
![]() |
d460d48684 | ||
![]() |
a6c6b3c0bd | ||
![]() |
48c92659fd | ||
![]() |
43219fe49e | ||
![]() |
edac220a42 | ||
![]() |
bdd479298b | ||
![]() |
9ed6cb636d | ||
![]() |
426a4f3a69 | ||
![]() |
ba61986e1d | ||
![]() |
162a40ca80 | ||
![]() |
d831597cc2 | ||
![]() |
4c90d7c12c | ||
![]() |
2ce1220ef5 | ||
![]() |
a35d78afd8 | ||
![]() |
b898d863c0 | ||
![]() |
3fa44b2e3f | ||
![]() |
857af4fde0 | ||
![]() |
a1b421a7fa | ||
![]() |
02fce160a9 | ||
![]() |
a4c228277b | ||
![]() |
43263b5eee | ||
![]() |
c001a4d830 | ||
![]() |
f8a3c4aa19 | ||
![]() |
1a681dcc1a | ||
![]() |
51b0fb0740 | ||
![]() |
66f5d71d1a | ||
![]() |
05163a558c | ||
![]() |
2fa6439af4 | ||
![]() |
e57f253632 | ||
![]() |
e3f23491c4 | ||
![]() |
b65a47429f | ||
![]() |
10cd2d092d | ||
![]() |
0cdecaade3 | ||
![]() |
0219308a08 | ||
![]() |
bff7f76c33 | ||
![]() |
a8485838e3 | ||
![]() |
b9adb793cd | ||
![]() |
3ade697ed3 | ||
![]() |
887a797ae6 | ||
![]() |
9ec2ef7f56 | ||
![]() |
b0f142a94b | ||
![]() |
a6c90a7237 | ||
![]() |
225e654f89 | ||
![]() |
16c5106cd3 | ||
![]() |
ea23fd3b7e | ||
![]() |
49750688ab | ||
![]() |
40a9699a9e | ||
![]() |
2f19ba3357 | ||
![]() |
59835c80f6 | ||
![]() |
cc82721565 | ||
![]() |
2b12aadc0d | ||
![]() |
140efa4766 | ||
![]() |
61ae7e669e | ||
![]() |
fb8e6825db | ||
![]() |
ae7de12bec | ||
![]() |
ab6d236594 | ||
![]() |
8215720b49 | ||
![]() |
7428ea4c7f | ||
![]() |
587a1a0f80 | ||
![]() |
50d70f8429 | ||
![]() |
69df85fdd6 | ||
![]() |
815a217536 | ||
![]() |
857f13b26c | ||
![]() |
2094b50553 | ||
![]() |
21aa667b9c | ||
![]() |
429ad3fc6b | ||
![]() |
02d212c1e4 | ||
![]() |
2b0ae177fa | ||
![]() |
77ad196a86 | ||
![]() |
eac88e5d50 | ||
![]() |
283092ff92 | ||
![]() |
075e2d1c6c | ||
![]() |
c3e96c4a55 | ||
![]() |
ad7ff86aa7 | ||
![]() |
3730dc74df | ||
![]() |
ae31a57541 | ||
![]() |
49ad3bccda | ||
![]() |
40563b0864 | ||
![]() |
595163619d | ||
![]() |
bac3b38153 | ||
![]() |
bbba06a85f | ||
![]() |
44f2be4afb | ||
![]() |
99ca87b7c4 | ||
![]() |
d8f1075491 | ||
![]() |
2485de7d44 | ||
![]() |
bf0d6f00da | ||
![]() |
922f221b09 | ||
![]() |
7b5dc7b33d | ||
![]() |
3794a999a3 | ||
![]() |
67527afcb8 | ||
![]() |
1b19b57109 | ||
![]() |
344979a2a8 | ||
![]() |
3680fcf389 | ||
![]() |
aeb5046298 | ||
![]() |
3cac519143 | ||
![]() |
222a97028a | ||
![]() |
a12240a0eb | ||
![]() |
23c72dfa69 | ||
![]() |
c3ce4738ec | ||
![]() |
43aaf52e46 | ||
![]() |
d9f5e1e736 | ||
![]() |
92864ed007 | ||
![]() |
3e47c93df8 | ||
![]() |
51c2d1f0bf | ||
![]() |
5efdcc24c8 | ||
![]() |
0511223ca5 | ||
![]() |
6d74c51e0e | ||
![]() |
e8d6dfec60 | ||
![]() |
db623461ee | ||
![]() |
3a058339be | ||
![]() |
a395ba865d | ||
![]() |
4dfdefc933 |
|
@ -1,2 +1,2 @@
|
|||
https://github.com/heroku/heroku-buildpack-ruby.git
|
||||
https://github.com/drogus/last-commit-sha-buildpack.git
|
||||
https://github.com/ryandotsmith/nginx-buildpack.git
|
||||
|
|
12
.gitignore
vendored
12
.gitignore
vendored
|
@ -1,6 +1,12 @@
|
|||
config/travis.yml
|
||||
.yardoc
|
||||
log/
|
||||
vendor
|
||||
config/database.yml
|
||||
config/nginx.conf
|
||||
config/skylight.yml
|
||||
|
||||
tmp/
|
||||
logs/
|
||||
|
||||
.yardoc
|
||||
.coverage
|
||||
*.env
|
||||
.ruby-gemset
|
||||
|
|
|
@ -1 +1 @@
|
|||
2.1.5
|
||||
2.2.3
|
||||
|
|
|
@ -2,7 +2,7 @@ language: ruby
|
|||
|
||||
sudo: false
|
||||
|
||||
rvm: 2.1.5
|
||||
rvm: 2.2.3
|
||||
|
||||
env:
|
||||
global:
|
||||
|
@ -18,4 +18,4 @@ services:
|
|||
- redis
|
||||
|
||||
before_script:
|
||||
- 'RAILS_ENV=test bundle exec rake db:create db:migrate --trace'
|
||||
- 'RAILS_ENV=test bundle exec rake db:create --trace'
|
||||
|
|
25
Gemfile
25
Gemfile
|
@ -1,14 +1,14 @@
|
|||
source 'https://rubygems.org'
|
||||
gemspec
|
||||
|
||||
ruby '2.1.2' if ENV.key?('DYNO')
|
||||
|
||||
gem 's3', github: 'travis-ci/s3'
|
||||
|
||||
gem 'travis-core', github: 'travis-ci/travis-core'
|
||||
gem 'travis-support', github: 'travis-ci/travis-support'
|
||||
gem 'travis-amqp', github: 'travis-ci/travis-amqp'
|
||||
gem 'travis-config', '~> 0.1.0'
|
||||
gem 'travis-sidekiqs', github: 'travis-ci/travis-sidekiqs', require: nil
|
||||
gem 'travis-settings', github: 'travis-ci/travis-settings'
|
||||
gem 'travis-sidekiqs', github: 'travis-ci/travis-sidekiqs'
|
||||
|
||||
gem 'travis-yaml', github: 'travis-ci/travis-yaml'
|
||||
gem 'mustermann', github: 'rkh/mustermann'
|
||||
gem 'sinatra'
|
||||
|
@ -16,11 +16,11 @@ gem 'sinatra-contrib', require: nil #github: 'sinatra/sinatra-contrib', require:
|
|||
|
||||
gem 'active_model_serializers'
|
||||
gem 'unicorn'
|
||||
gem 'sentry-raven', github: 'getsentry/raven-ruby'
|
||||
gem 'sentry-raven'
|
||||
gem 'yard-sinatra', github: 'rkh/yard-sinatra'
|
||||
gem 'rack-contrib', github: 'rack/rack-contrib'
|
||||
gem 'rack-contrib'
|
||||
gem 'rack-cache', github: 'rtomayko/rack-cache'
|
||||
gem 'rack-attack'
|
||||
gem 'rack-attack', '5.0.0.beta1'
|
||||
gem 'gh'
|
||||
gem 'bunny', '~> 0.8.0'
|
||||
gem 'dalli'
|
||||
|
@ -30,12 +30,23 @@ gem 'metriks-librato_metrics', github: 'eric/metriks-librato_metrics'
|
|||
gem 'micro_migrations'
|
||||
gem 'simplecov'
|
||||
gem 'skylight', '~> 0.6.0.beta.1'
|
||||
gem 'stackprof'
|
||||
gem 'netaddr'
|
||||
|
||||
gem 'jemalloc'
|
||||
gem 'customerio'
|
||||
|
||||
group :development, :test do
|
||||
gem 'travis-migrations', github: 'travis-ci/travis-migrations'
|
||||
end
|
||||
|
||||
group :test do
|
||||
gem 'rspec', '~> 2.13'
|
||||
gem 'rspec-its'
|
||||
gem 'factory_girl', '~> 2.4.0'
|
||||
gem 'mocha', '~> 0.12'
|
||||
gem 'database_cleaner', '~> 0.8.0'
|
||||
gem 'timecop', '~> 0.8.0'
|
||||
end
|
||||
|
||||
group :development do
|
||||
|
|
334
Gemfile.lock
334
Gemfile.lock
|
@ -1,28 +1,13 @@
|
|||
GIT
|
||||
remote: git://github.com/eric/metriks-librato_metrics.git
|
||||
revision: ccbeb751ec5fc4edfe446d8a67a423b96ebe86c7
|
||||
revision: 2c124f024fd2e34378260cd24b0e8687ff9bd196
|
||||
specs:
|
||||
metriks-librato_metrics (1.0.2)
|
||||
metriks-librato_metrics (1.0.5)
|
||||
metriks (>= 0.9.9.6)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/getsentry/raven-ruby.git
|
||||
revision: 84392e5db701f0b5c66802aab9cc82ef9a5ad830
|
||||
specs:
|
||||
sentry-raven (0.10.1)
|
||||
faraday (>= 0.7.6)
|
||||
uuidtools
|
||||
|
||||
GIT
|
||||
remote: git://github.com/rack/rack-contrib.git
|
||||
revision: 1b11346d729efd88b274cd7f704e0bca9eb3de7a
|
||||
specs:
|
||||
rack-contrib (1.2.0)
|
||||
rack (>= 0.9.1)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/rkh/mustermann.git
|
||||
revision: 01df7fe671838d6caadac278d9704b5cd3c7b999
|
||||
revision: 9611951c5c789ad8227a740ae142c157a8bf7401
|
||||
specs:
|
||||
mustermann (0.4.0)
|
||||
tool (~> 0.2)
|
||||
|
@ -36,9 +21,9 @@ GIT
|
|||
|
||||
GIT
|
||||
remote: git://github.com/rtomayko/rack-cache.git
|
||||
revision: d00e6e491fcc7bdca9c27d735abde5c4fdb48cd9
|
||||
revision: 2d6618172c39c53dceab2e2946d87496154f3e52
|
||||
specs:
|
||||
rack-cache (1.2)
|
||||
rack-cache (1.6.1)
|
||||
rack (>= 0.4)
|
||||
|
||||
GIT
|
||||
|
@ -49,45 +34,42 @@ GIT
|
|||
proxies (~> 0.2.0)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/travis-ci/travis-core.git
|
||||
revision: 9ef018a267e94251dbaac54503a410baca71d1c6
|
||||
remote: git://github.com/travis-ci/travis-amqp.git
|
||||
revision: 3966b3651adfd1c544f53d49d5986ac16cd9c4bc
|
||||
specs:
|
||||
travis-core (0.0.1)
|
||||
actionmailer (~> 3.2.19)
|
||||
activerecord (~> 3.2.19)
|
||||
coder (~> 0.4.0)
|
||||
data_migrations (~> 0.0.1)
|
||||
gh
|
||||
hashr (~> 0.0.19)
|
||||
metriks (~> 0.9.7)
|
||||
multi_json
|
||||
pusher (~> 0.14.0)
|
||||
railties (~> 3.2.19)
|
||||
rake
|
||||
redis (~> 3.0)
|
||||
rollout (~> 1.1.0)
|
||||
s3 (~> 0.3)
|
||||
simple_states (~> 1.0.0)
|
||||
thor (~> 0.14.6)
|
||||
travis-config (~> 0.1.0)
|
||||
virtus (~> 1.0.0)
|
||||
travis-amqp (0.0.1)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/travis-ci/travis-migrations.git
|
||||
revision: dc432e45354287c617c3ae07a72e9e3c4be012cd
|
||||
specs:
|
||||
travis-migrations (0.0.2)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/travis-ci/travis-settings.git
|
||||
revision: d510e63b6c6f059cccae141c265e7a0c7236d1fd
|
||||
specs:
|
||||
travis-settings (0.0.1)
|
||||
activemodel
|
||||
virtus
|
||||
|
||||
GIT
|
||||
remote: git://github.com/travis-ci/travis-sidekiqs.git
|
||||
revision: 21a2fee158e25252dd78f5fa31e81b4f6583be23
|
||||
revision: c5d4a4abc6c3737f9c43d3333efb94daa18b9fbb
|
||||
specs:
|
||||
travis-sidekiqs (0.0.1)
|
||||
redis-namespace
|
||||
sidekiq
|
||||
|
||||
GIT
|
||||
remote: git://github.com/travis-ci/travis-support.git
|
||||
revision: 4fdd220ed7b06a12951e5d74a763c05a80eb0d20
|
||||
revision: 2cd02d2a06fdd1e2fc2f129148c168b56f7c190f
|
||||
specs:
|
||||
travis-support (0.0.1)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/travis-ci/travis-yaml.git
|
||||
revision: 1630d576d221aea2340615e87f402df7889b5176
|
||||
revision: 032caed23af8ed1ed55e9204bb91316f3ada2f74
|
||||
specs:
|
||||
travis-yaml (0.2.0)
|
||||
|
||||
|
@ -95,29 +77,36 @@ PATH
|
|||
remote: .
|
||||
specs:
|
||||
travis-api (0.0.1)
|
||||
activerecord (~> 3.2.19)
|
||||
coder (~> 0.4.0)
|
||||
composite_primary_keys (~> 5.0)
|
||||
google-api-client (~> 0.9.4)
|
||||
hashr
|
||||
memcachier
|
||||
multi_json
|
||||
mustermann (~> 0.4)
|
||||
pg (~> 0.13.2)
|
||||
pg
|
||||
pusher (~> 0.14.0)
|
||||
rack-contrib (~> 1.1)
|
||||
rack-ssl (~> 1.3, >= 1.3.3)
|
||||
railties (~> 3.2.19)
|
||||
redcarpet (~> 2.1)
|
||||
redis (~> 3.0)
|
||||
rollout (~> 1.1.0)
|
||||
simple_states (~> 1.0.0)
|
||||
sinatra (~> 1.3)
|
||||
sinatra-contrib (~> 1.3)
|
||||
thin (~> 1.4)
|
||||
travis-core
|
||||
tool
|
||||
travis-support
|
||||
useragent
|
||||
virtus (~> 1.0.0)
|
||||
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
actionmailer (3.2.19)
|
||||
actionpack (= 3.2.19)
|
||||
mail (~> 2.5.4)
|
||||
actionpack (3.2.19)
|
||||
activemodel (= 3.2.19)
|
||||
activesupport (= 3.2.19)
|
||||
actionpack (3.2.22.2)
|
||||
activemodel (= 3.2.22.2)
|
||||
activesupport (= 3.2.22.2)
|
||||
builder (~> 3.0.0)
|
||||
erubis (~> 2.7.0)
|
||||
journey (~> 1.0.4)
|
||||
|
@ -125,85 +114,103 @@ GEM
|
|||
rack-cache (~> 1.2)
|
||||
rack-test (~> 0.6.1)
|
||||
sprockets (~> 2.2.1)
|
||||
active_model_serializers (0.9.0)
|
||||
active_model_serializers (0.9.5)
|
||||
activemodel (>= 3.2)
|
||||
activemodel (3.2.19)
|
||||
activesupport (= 3.2.19)
|
||||
activemodel (3.2.22.2)
|
||||
activesupport (= 3.2.22.2)
|
||||
builder (~> 3.0.0)
|
||||
activerecord (3.2.19)
|
||||
activemodel (= 3.2.19)
|
||||
activesupport (= 3.2.19)
|
||||
activerecord (3.2.22.2)
|
||||
activemodel (= 3.2.22.2)
|
||||
activesupport (= 3.2.22.2)
|
||||
arel (~> 3.0.2)
|
||||
tzinfo (~> 0.3.29)
|
||||
activesupport (3.2.19)
|
||||
activesupport (3.2.22.2)
|
||||
i18n (~> 0.6, >= 0.6.4)
|
||||
multi_json (~> 1.0)
|
||||
addressable (2.3.6)
|
||||
addressable (2.4.0)
|
||||
arel (3.0.3)
|
||||
atomic (1.1.16)
|
||||
atomic (1.1.99)
|
||||
avl_tree (1.1.3)
|
||||
axiom-types (0.1.1)
|
||||
descendants_tracker (~> 0.0.4)
|
||||
ice_nine (~> 0.11.0)
|
||||
thread_safe (~> 0.3, >= 0.3.1)
|
||||
backports (3.6.4)
|
||||
backports (3.6.8)
|
||||
builder (3.0.4)
|
||||
bunny (0.8.0)
|
||||
celluloid (0.16.0)
|
||||
timers (~> 4.0.0)
|
||||
coder (0.4.0)
|
||||
coderay (1.1.0)
|
||||
coderay (1.1.1)
|
||||
coercible (1.0.0)
|
||||
descendants_tracker (~> 0.0.1)
|
||||
composite_primary_keys (5.0.14)
|
||||
activerecord (~> 3.2.0, >= 3.2.9)
|
||||
connection_pool (2.1.1)
|
||||
daemons (1.1.9)
|
||||
dalli (2.7.2)
|
||||
data_migrations (0.0.1)
|
||||
activerecord
|
||||
rake
|
||||
concurrent-ruby (1.0.2)
|
||||
connection_pool (2.2.0)
|
||||
customerio (1.0.0)
|
||||
multi_json (~> 1.0)
|
||||
dalli (2.7.6)
|
||||
database_cleaner (0.8.0)
|
||||
descendants_tracker (0.0.4)
|
||||
thread_safe (~> 0.3, >= 0.3.1)
|
||||
diff-lcs (1.2.5)
|
||||
docile (1.1.5)
|
||||
dotenv (0.7.0)
|
||||
equalizer (0.0.9)
|
||||
equalizer (0.0.11)
|
||||
erubis (2.7.0)
|
||||
eventmachine (1.0.7)
|
||||
factory_girl (2.4.2)
|
||||
activesupport
|
||||
faraday (0.9.1)
|
||||
faraday (0.9.2)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ffi (1.9.6)
|
||||
foreman (0.64.0)
|
||||
dotenv (~> 0.7.0)
|
||||
thor (>= 0.13.6)
|
||||
gh (0.13.3)
|
||||
ffi (1.9.10)
|
||||
foreman (0.82.0)
|
||||
thor (~> 0.19.1)
|
||||
gh (0.14.0)
|
||||
addressable
|
||||
backports
|
||||
faraday (~> 0.8)
|
||||
multi_json (~> 1.0)
|
||||
net-http-persistent (>= 2.7)
|
||||
net-http-pipeline
|
||||
git-version-bump (0.15.1)
|
||||
google-api-client (0.9.8)
|
||||
addressable (~> 2.3)
|
||||
googleauth (~> 0.5)
|
||||
httpclient (~> 2.7)
|
||||
hurley (~> 0.1)
|
||||
memoist (~> 0.11)
|
||||
mime-types (>= 1.6)
|
||||
representable (~> 2.3.0)
|
||||
retriable (~> 2.0)
|
||||
thor (~> 0.19)
|
||||
googleauth (0.5.1)
|
||||
faraday (~> 0.9)
|
||||
jwt (~> 1.4)
|
||||
logging (~> 2.0)
|
||||
memoist (~> 0.12)
|
||||
multi_json (~> 1.11)
|
||||
os (~> 0.9)
|
||||
signet (~> 0.7)
|
||||
hashr (0.0.22)
|
||||
hike (1.2.3)
|
||||
hitimes (1.2.2)
|
||||
httpclient (2.6.0.1)
|
||||
i18n (0.6.11)
|
||||
ice_nine (0.11.1)
|
||||
hitimes (1.2.4)
|
||||
httpclient (2.8.0)
|
||||
hurley (0.2)
|
||||
i18n (0.7.0)
|
||||
ice_nine (0.11.2)
|
||||
jemalloc (1.0.1)
|
||||
journey (1.0.4)
|
||||
json (1.8.1)
|
||||
kgio (2.9.2)
|
||||
listen (1.0.3)
|
||||
rb-fsevent (>= 0.9.3)
|
||||
rb-inotify (>= 0.9)
|
||||
rb-kqueue (>= 0.2)
|
||||
mail (2.5.4)
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
json (1.8.3)
|
||||
jwt (1.5.4)
|
||||
kgio (2.10.0)
|
||||
listen (3.1.5)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
ruby_dep (~> 1.2)
|
||||
little-plugger (1.1.4)
|
||||
logging (2.1.0)
|
||||
little-plugger (~> 1.1)
|
||||
multi_json (~> 1.10)
|
||||
memcachier (0.0.2)
|
||||
memoist (0.14.0)
|
||||
metaclass (0.0.4)
|
||||
method_source (0.8.2)
|
||||
metriks (0.9.9.6)
|
||||
|
@ -216,52 +223,58 @@ GEM
|
|||
mime-types (1.25.1)
|
||||
mocha (0.14.0)
|
||||
metaclass (~> 0.0.1)
|
||||
multi_json (1.10.1)
|
||||
multi_json (1.12.1)
|
||||
multipart-post (2.0.0)
|
||||
net-http-persistent (2.9.4)
|
||||
net-http-pipeline (1.0.1)
|
||||
pg (0.13.2)
|
||||
polyglot (0.3.5)
|
||||
netaddr (1.5.1)
|
||||
os (0.9.6)
|
||||
pg (0.18.4)
|
||||
proxies (0.2.1)
|
||||
pry (0.10.1)
|
||||
pry (0.10.3)
|
||||
coderay (~> 1.1.0)
|
||||
method_source (~> 0.8.1)
|
||||
slop (~> 3.4)
|
||||
pusher (0.14.4)
|
||||
pusher (0.14.6)
|
||||
httpclient (~> 2.5)
|
||||
multi_json (~> 1.0)
|
||||
signature (~> 0.1.8)
|
||||
rack (1.4.5)
|
||||
rack-attack (4.2.0)
|
||||
pusher-signature (~> 0.1.8)
|
||||
pusher-signature (0.1.8)
|
||||
rack (1.4.7)
|
||||
rack-attack (5.0.0.beta1)
|
||||
rack
|
||||
rack-contrib (1.4.0)
|
||||
git-version-bump (~> 0.15)
|
||||
rack (~> 1.4)
|
||||
rack-protection (1.5.3)
|
||||
rack
|
||||
rack-ssl (1.3.4)
|
||||
rack
|
||||
rack-test (0.6.2)
|
||||
rack-test (0.6.3)
|
||||
rack (>= 1.0)
|
||||
railties (3.2.19)
|
||||
actionpack (= 3.2.19)
|
||||
activesupport (= 3.2.19)
|
||||
railties (3.2.22.2)
|
||||
actionpack (= 3.2.22.2)
|
||||
activesupport (= 3.2.22.2)
|
||||
rack-ssl (~> 1.3.2)
|
||||
rake (>= 0.8.7)
|
||||
rdoc (~> 3.4)
|
||||
thor (>= 0.14.6, < 2.0)
|
||||
raindrops (0.13.0)
|
||||
raindrops (0.16.0)
|
||||
rake (0.9.6)
|
||||
rb-fsevent (0.9.4)
|
||||
rb-inotify (0.9.5)
|
||||
ffi (>= 0.5.0)
|
||||
rb-kqueue (0.2.3)
|
||||
rb-fsevent (0.9.7)
|
||||
rb-inotify (0.9.7)
|
||||
ffi (>= 0.5.0)
|
||||
rdoc (3.12.2)
|
||||
json (~> 1.4)
|
||||
redcarpet (2.3.0)
|
||||
redis (3.1.0)
|
||||
redis-namespace (1.5.1)
|
||||
redis (3.3.0)
|
||||
redis-namespace (1.5.2)
|
||||
redis (~> 3.0, >= 3.0.4)
|
||||
rerun (0.8.2)
|
||||
listen (~> 1.0.3)
|
||||
representable (2.3.0)
|
||||
uber (~> 0.0.7)
|
||||
rerun (0.11.0)
|
||||
listen (~> 3.0)
|
||||
retriable (2.1.0)
|
||||
rollout (1.1.0)
|
||||
rspec (2.99.0)
|
||||
rspec-core (~> 2.99.0)
|
||||
|
@ -270,64 +283,64 @@ GEM
|
|||
rspec-core (2.99.2)
|
||||
rspec-expectations (2.99.2)
|
||||
diff-lcs (>= 1.1.3, < 2.0)
|
||||
rspec-mocks (2.99.2)
|
||||
sidekiq (3.3.0)
|
||||
celluloid (>= 0.16.0)
|
||||
connection_pool (>= 2.0.0)
|
||||
json
|
||||
redis (>= 3.0.6)
|
||||
redis-namespace (>= 1.3.1)
|
||||
signature (0.1.8)
|
||||
rspec-its (1.0.1)
|
||||
rspec-core (>= 2.99.0.beta1)
|
||||
rspec-expectations (>= 2.99.0.beta1)
|
||||
rspec-mocks (2.99.4)
|
||||
ruby_dep (1.3.1)
|
||||
sentry-raven (1.0.0)
|
||||
faraday (>= 0.7.6)
|
||||
sidekiq (4.1.2)
|
||||
concurrent-ruby (~> 1.0)
|
||||
connection_pool (~> 2.2, >= 2.2.0)
|
||||
redis (~> 3.2, >= 3.2.1)
|
||||
signet (0.7.2)
|
||||
addressable (~> 2.3)
|
||||
faraday (~> 0.9)
|
||||
jwt (~> 1.5)
|
||||
multi_json (~> 1.10)
|
||||
simple_states (1.0.1)
|
||||
activesupport
|
||||
hashr (~> 0.0.10)
|
||||
simplecov (0.9.1)
|
||||
simplecov (0.11.2)
|
||||
docile (~> 1.1.0)
|
||||
multi_json (~> 1.0)
|
||||
simplecov-html (~> 0.8.0)
|
||||
simplecov-html (0.8.0)
|
||||
sinatra (1.4.5)
|
||||
json (~> 1.8)
|
||||
simplecov-html (~> 0.10.0)
|
||||
simplecov-html (0.10.0)
|
||||
sinatra (1.4.6)
|
||||
rack (~> 1.4)
|
||||
rack-protection (~> 1.4)
|
||||
tilt (~> 1.3, >= 1.3.4)
|
||||
sinatra-contrib (1.4.2)
|
||||
tilt (>= 1.3, < 3)
|
||||
sinatra-contrib (1.4.7)
|
||||
backports (>= 2.0)
|
||||
multi_json
|
||||
rack-protection
|
||||
rack-test
|
||||
sinatra (~> 1.4.0)
|
||||
tilt (~> 1.3)
|
||||
skylight (0.6.0.beta.1)
|
||||
tilt (>= 1.3, < 3)
|
||||
skylight (0.6.2.beta.2)
|
||||
activesupport (>= 3.0.0)
|
||||
slop (3.6.0)
|
||||
sprockets (2.2.2)
|
||||
sprockets (2.2.3)
|
||||
hike (~> 1.2)
|
||||
multi_json (~> 1.0)
|
||||
rack (~> 1.0)
|
||||
tilt (~> 1.1, != 1.3.0)
|
||||
thin (1.6.3)
|
||||
daemons (~> 1.0, >= 1.0.9)
|
||||
eventmachine (~> 1.0)
|
||||
rack (~> 1.0)
|
||||
thor (0.14.6)
|
||||
thread_safe (0.3.4)
|
||||
stackprof (0.2.9)
|
||||
thor (0.19.1)
|
||||
thread_safe (0.3.5)
|
||||
tilt (1.4.1)
|
||||
timers (4.0.1)
|
||||
hitimes
|
||||
timecop (0.8.1)
|
||||
tool (0.2.3)
|
||||
travis-config (0.1.0)
|
||||
travis-config (0.1.4)
|
||||
hashr (~> 0.0)
|
||||
treetop (1.4.15)
|
||||
polyglot
|
||||
polyglot (>= 0.3.1)
|
||||
tzinfo (0.3.42)
|
||||
unicorn (4.8.3)
|
||||
tzinfo (0.3.49)
|
||||
uber (0.0.15)
|
||||
unicorn (5.1.0)
|
||||
kgio (~> 2.6)
|
||||
rack
|
||||
raindrops (~> 0.7)
|
||||
useragent (0.10.0)
|
||||
uuidtools (2.1.5)
|
||||
virtus (1.0.4)
|
||||
useragent (0.16.7)
|
||||
virtus (1.0.5)
|
||||
axiom-types (~> 0.1)
|
||||
coercible (~> 1.0)
|
||||
descendants_tracker (~> 0.0, >= 0.0.3)
|
||||
|
@ -340,35 +353,46 @@ PLATFORMS
|
|||
DEPENDENCIES
|
||||
active_model_serializers
|
||||
bunny (~> 0.8.0)
|
||||
customerio
|
||||
dalli
|
||||
database_cleaner (~> 0.8.0)
|
||||
factory_girl (~> 2.4.0)
|
||||
foreman
|
||||
gh
|
||||
jemalloc
|
||||
metriks (= 0.9.9.6)
|
||||
metriks-librato_metrics!
|
||||
micro_migrations
|
||||
mocha (~> 0.12)
|
||||
mustermann!
|
||||
netaddr
|
||||
pry
|
||||
rack-attack
|
||||
rack-attack (= 5.0.0.beta1)
|
||||
rack-cache!
|
||||
rack-contrib!
|
||||
rack-contrib
|
||||
rake (~> 0.9.2)
|
||||
rb-fsevent (~> 0.9.1)
|
||||
rerun
|
||||
rspec (~> 2.13)
|
||||
rspec-its
|
||||
s3!
|
||||
sentry-raven!
|
||||
sentry-raven
|
||||
simplecov
|
||||
sinatra
|
||||
sinatra-contrib
|
||||
skylight (~> 0.6.0.beta.1)
|
||||
stackprof
|
||||
timecop (~> 0.8.0)
|
||||
travis-amqp!
|
||||
travis-api!
|
||||
travis-config (~> 0.1.0)
|
||||
travis-core!
|
||||
travis-migrations!
|
||||
travis-settings!
|
||||
travis-sidekiqs!
|
||||
travis-support!
|
||||
travis-yaml!
|
||||
unicorn
|
||||
yard-sinatra!
|
||||
|
||||
BUNDLED WITH
|
||||
1.12.5
|
||||
|
|
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Travis CI GmbH
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
7
Procfile
7
Procfile
|
@ -1,3 +1,4 @@
|
|||
web: bundle exec ./script/server
|
||||
console: bundle exec ./script/console
|
||||
sidekiq: bundle exec sidekiq -c 5 -r ./lib/travis/sidekiq.rb -q build_cancellations, -q build_restarts, -q job_cancellations, -q job_restarts
|
||||
web: ./script/server
|
||||
console: bundle exec je ./script/console
|
||||
sidekiq: bundle exec je sidekiq -c 4 -r ./lib/travis/sidekiq.rb -q build_cancellations, -q build_restarts, -q job_cancellations, -q job_restarts
|
||||
start_crons: ./script/start_crons
|
||||
|
|
102
README.md
102
README.md
|
@ -4,47 +4,68 @@ This is the app running on https://api.travis-ci.org/
|
|||
|
||||
## Requirements
|
||||
|
||||
You will need the following packages to get travis-api to work:
|
||||
|
||||
1. PostgreSQL 9.3 or higher
|
||||
1. Redis
|
||||
1. RabbitMQ
|
||||
2. Bundler
|
||||
3. Redis Server
|
||||
4. *Optional:* RabbitMQ Server
|
||||
5. Nginx -
|
||||
*If working in Ubuntu please install nginx manually from source: Download and extract latest nginx version, open a terminal in extracted folder and then run the following:*
|
||||
```sh-session
|
||||
$ sudo apt-get install libpcre3 libpcre3-dev
|
||||
$ auto/configure --user=$USER
|
||||
$ make
|
||||
$ sudo make install
|
||||
$ sudo ln -s /usr/local/nginx/sbin/nginx /bin/nginx
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
### Setup
|
||||
|
||||
$ bundle install
|
||||
|
||||
```sh-session
|
||||
$ bundle install
|
||||
```
|
||||
### Database setup
|
||||
|
||||
1. `rake db:create db:structure:load`
|
||||
1. Clone `travis-logs` and copy the `logs` database (assume the PostgreSQL user is `postgres`):
|
||||
*You might need to create a role first. For this you should run the following:*
|
||||
```sh-session
|
||||
cd ..
|
||||
git clone https://github.com/travis-ci/travis-logs.git
|
||||
cd travis-logs
|
||||
rvm jruby do bundle exec rake db:migrate # `travis-logs` requires JRuby
|
||||
psql -c "DROP TABLE IF EXISTS logs CASCADE" -U postgres travis_development
|
||||
pg_dump -t logs travis_logs_development | psql -U postgres travis_development
|
||||
$ sudo -u postgres psql -c "CREATE USER yourusername WITH SUPERUSER PASSWORD 'yourpassword'"
|
||||
```
|
||||
|
||||
Repeat the database steps for `RAILS_ENV=test`.
|
||||
NB detail for how `rake` sets up the database can be found in the `Rakefile`. In the `namespace :db` block you will see the database name is configured using the environment variable RAILS_ENV. If you are using a different configuration you will have to make your own adjustments.
|
||||
```sh-session
|
||||
RAILS_ENV=test rake db:create db:structure:load
|
||||
pushd ../travis-logs
|
||||
RAILS_ENV=test rvm jruby do bundle exec rake db:migrate
|
||||
psql -c "DROP TABLE IF EXISTS logs CASCADE" -U postgres travis_test
|
||||
pg_dump -t logs travis_logs_test | psql -U postgres travis_test
|
||||
popd
|
||||
$ RAILS_ENV=development bundle exec rake db:create
|
||||
$ RAILS_ENV=test bundle exec rake db:create
|
||||
```
|
||||
#### Optional
|
||||
Clone `travis-logs` and copy the `logs` database (assume the PostgreSQL user is `postgres`):
|
||||
```sh-session
|
||||
$ cd ..
|
||||
$ git clone https://github.com/travis-ci/travis-logs.git
|
||||
$ cd travis-logs
|
||||
$ rvm jruby do bundle exec rake db:migrate # `travis-logs` requires JRuby
|
||||
$ psql -c "DROP TABLE IF EXISTS logs CASCADE" -U postgres travis_development
|
||||
$ pg_dump -t logs travis_logs_development | psql -U postgres travis_development
|
||||
|
||||
$ RAILS_ENV=test bundle exec rake db:create
|
||||
$ pushd ../travis-logs
|
||||
$ RAILS_ENV=test rvm jruby do bundle exec rake db:migrate
|
||||
$ psql -c "DROP TABLE IF EXISTS logs CASCADE" -U postgres travis_test
|
||||
$ pg_dump -t logs travis_logs_test | psql -U postgres travis_test
|
||||
$ popd
|
||||
```
|
||||
|
||||
|
||||
### Run tests
|
||||
|
||||
$ rake spec
|
||||
|
||||
```sh-session
|
||||
$ bundle exec rake
|
||||
```
|
||||
### Run the server
|
||||
|
||||
$ script/server
|
||||
```sh-session
|
||||
$ bundle exec script/server
|
||||
```
|
||||
If you have problems with Nginx because the websocket is already in use, try restarting your computer.
|
||||
|
||||
## Contributing
|
||||
|
||||
|
@ -56,33 +77,4 @@ popd
|
|||
|
||||
### API documentation
|
||||
|
||||
We use source code comments to add documentation. If the server is running, you
|
||||
can browse an HTML documenation at [`/docs`](http://localhost:5000/docs).
|
||||
|
||||
### Project architecture
|
||||
|
||||
lib
|
||||
`-- travis
|
||||
`-- api
|
||||
`-- app
|
||||
|-- endpoint # API endpoints
|
||||
|-- extensions # Sinatra extensions
|
||||
|-- helpers # Sinatra helpers
|
||||
`-- middleware # Rack middleware
|
||||
|
||||
Classes inheriting from `Endpoint` or `Middleware`, they will automatically be
|
||||
set up properly.
|
||||
|
||||
Each endpoint class gets mapped to a prefix, which defaults to the snake-case
|
||||
class name (i.e. `Travis::Api::App::Profile` will map to `/profile`).
|
||||
It can be overridden by setting `:prefix`:
|
||||
|
||||
``` ruby
|
||||
require 'travis/api/app'
|
||||
|
||||
class Travis::Api::App
|
||||
class MyRouts < Endpoint
|
||||
set :prefix, '/awesome'
|
||||
end
|
||||
end
|
||||
```
|
||||
v3 documentation can be found at https://developer.travis-ci.org which is a repository that can be found at https://github.com/travis-pro/developer
|
||||
|
|
149
Rakefile
149
Rakefile
|
@ -1,127 +1,34 @@
|
|||
require 'bundler/setup'
|
||||
require 'travis'
|
||||
require 'travis/engine'
|
||||
|
||||
begin
|
||||
ENV['SCHEMA'] = File.expand_path('../db/schema.rb', $:.detect { |p| p.include?('travis-core') })
|
||||
require 'micro_migrations'
|
||||
rescue LoadError
|
||||
# we can't load micro migrations on production
|
||||
end
|
||||
require 'travis'
|
||||
|
||||
begin
|
||||
require 'rspec/core/rake_task'
|
||||
RSpec::Core::RakeTask.new
|
||||
task default: :spec
|
||||
rescue LoadError
|
||||
warn "could not load rspec"
|
||||
end
|
||||
|
||||
desc "generate gemspec"
|
||||
task 'travis-api.gemspec' do
|
||||
content = File.read 'travis-api.gemspec'
|
||||
|
||||
fields = {
|
||||
authors: `git shortlog -sn`.scan(/[^\d\s].*/),
|
||||
email: `git shortlog -sne`.scan(/[^<]+@[^>]+/),
|
||||
files: `git ls-files`.split("\n").reject { |f| f =~ /^(\.|Gemfile)/ }
|
||||
}
|
||||
|
||||
fields.each do |field, values|
|
||||
updated = " s.#{field} = ["
|
||||
updated << values.map { |v| "\n %p" % v }.join(',')
|
||||
updated << "\n ]"
|
||||
content.sub!(/ s\.#{field} = \[\n( .*\n)* \]/, updated)
|
||||
end
|
||||
|
||||
File.open('travis-api.gemspec', 'w') { |f| f << content }
|
||||
end
|
||||
|
||||
task default: 'travis-api.gemspec'
|
||||
|
||||
tasks_path = File.expand_path('../lib/tasks/*.rake', __FILE__)
|
||||
Dir.glob(tasks_path).each { |r| import r }
|
||||
|
||||
module ActiveRecord
|
||||
class Migration
|
||||
class << self
|
||||
attr_accessor :disable_ddl_transaction
|
||||
end
|
||||
|
||||
# Disable DDL transactions for this migration.
|
||||
def self.disable_ddl_transaction!
|
||||
@disable_ddl_transaction = true
|
||||
end
|
||||
|
||||
def disable_ddl_transaction # :nodoc:
|
||||
self.class.disable_ddl_transaction
|
||||
namespace :db do
|
||||
env = ENV["RAILS_ENV"]
|
||||
if env != 'production'
|
||||
desc "Create and migrate the #{env} database"
|
||||
task :create do
|
||||
sh "createdb travis_#{env}" rescue nil
|
||||
sh "psql -q travis_#{env} < #{Gem.loaded_specs['travis-migrations'].full_gem_path}/db/structure.sql"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Migrator
|
||||
def use_transaction?(migration)
|
||||
!migration.disable_ddl_transaction && Base.connection.supports_ddl_transactions?
|
||||
end
|
||||
# begin
|
||||
# require 'rspec'
|
||||
# require 'rspec/core/rake_task'
|
||||
# RSpec::Core::RakeTask.new(:spec)
|
||||
#
|
||||
# RSpec::Core::RakeTask.new(:spec_core) do |t|
|
||||
# t.pattern = 'spec_core/**{,/*/**}/*_spec.rb'
|
||||
# end
|
||||
#
|
||||
# task :default => [:spec]
|
||||
# rescue LoadError => e
|
||||
# puts e.inspect
|
||||
# end
|
||||
|
||||
def ddl_transaction(migration, &block)
|
||||
if use_transaction?(migration)
|
||||
Base.transaction { block.call }
|
||||
else
|
||||
block.call
|
||||
end
|
||||
end
|
||||
|
||||
def migrate(&block)
|
||||
current = migrations.detect { |m| m.version == current_version }
|
||||
target = migrations.detect { |m| m.version == @target_version }
|
||||
|
||||
if target.nil? && @target_version && @target_version > 0
|
||||
raise UnknownMigrationVersionError.new(@target_version)
|
||||
end
|
||||
|
||||
start = up? ? 0 : (migrations.index(current) || 0)
|
||||
finish = migrations.index(target) || migrations.size - 1
|
||||
runnable = migrations[start..finish]
|
||||
|
||||
# skip the last migration if we're headed down, but not ALL the way down
|
||||
runnable.pop if down? && target
|
||||
|
||||
ran = []
|
||||
runnable.each do |migration|
|
||||
if block && !block.call(migration)
|
||||
next
|
||||
end
|
||||
|
||||
Base.logger.info "Migrating to #{migration.name} (#{migration.version})" if Base.logger
|
||||
|
||||
seen = migrated.include?(migration.version.to_i)
|
||||
|
||||
# On our way up, we skip migrating the ones we've already migrated
|
||||
next if up? && seen
|
||||
|
||||
# On our way down, we skip reverting the ones we've never migrated
|
||||
if down? && !seen
|
||||
migration.announce 'never migrated, skipping'; migration.write
|
||||
next
|
||||
end
|
||||
|
||||
begin
|
||||
ddl_transaction(migration) do
|
||||
migration.migrate(@direction)
|
||||
record_version_state_after_migrating(migration.version)
|
||||
end
|
||||
ran << migration
|
||||
rescue => e
|
||||
canceled_msg = Base.connection.supports_ddl_transactions? ? "this and " : ""
|
||||
raise StandardError, "An error has occurred, #{canceled_msg}all later migrations canceled:\n\n#{e}", e.backtrace
|
||||
end
|
||||
end
|
||||
ran
|
||||
end
|
||||
end
|
||||
|
||||
class MigrationProxy
|
||||
delegate :disable_ddl_transaction, to: :migration
|
||||
# not sure how else to include the spec_helper
|
||||
namespace :spec do
|
||||
desc 'Run all specs'
|
||||
task :all do
|
||||
sh 'bundle exec rspec -r spec_helper spec'
|
||||
end
|
||||
end
|
||||
|
||||
task :default => :'spec:all'
|
||||
|
|
|
@ -1,3 +1,82 @@
|
|||
#!/bin/sh
|
||||
#!/usr/bin/env bash
|
||||
|
||||
"$@"
|
||||
# make sure we kill all child processes once done
|
||||
trap '{ pkill -P $$; rm -f config/nginx.conf; exit 255; }' EXIT
|
||||
|
||||
if [ -f bin/nginx ]; then
|
||||
nginx=bin/nginx
|
||||
else
|
||||
which nginx &>/dev/null || { echo "nginx not found" && exit 1; }
|
||||
nginx=nginx
|
||||
fi
|
||||
|
||||
psmgr=$tmp_dir/nginx-buildpack-wait
|
||||
rm -f $psmgr
|
||||
mkfifo $psmgr
|
||||
|
||||
#Evaluate config to get $PORT
|
||||
erb config/nginx.conf.erb > config/nginx.conf
|
||||
|
||||
n=1
|
||||
while getopts :f option ${@:1:2}
|
||||
do
|
||||
case "${option}"
|
||||
in
|
||||
f) FORCE=$OPTIND; n=$((n+1));;
|
||||
esac
|
||||
done
|
||||
|
||||
#Initialize log directory.
|
||||
mkdir -p logs/nginx
|
||||
touch logs/nginx/access.log logs/nginx/error.log
|
||||
echo 'buildpack=nginx at=logs-initialized'
|
||||
|
||||
#Start log redirection.
|
||||
(
|
||||
#Redirect NGINX logs to stdout.
|
||||
tail -qF -n 0 logs/nginx/*.log
|
||||
echo 'logs' >$psmgr
|
||||
) &
|
||||
|
||||
#Start App Server
|
||||
(
|
||||
#Take the command passed to this bin and start it.
|
||||
#E.g. bin/start-nginx bundle exec unicorn -c config/unicorn.rb
|
||||
COMMAND=${@:$n}
|
||||
echo "buildpack=nginx at=start-app cmd=$COMMAND"
|
||||
$COMMAND
|
||||
echo 'app' >$psmgr
|
||||
) &
|
||||
|
||||
if [[ -z "$FORCE" ]]
|
||||
then
|
||||
FILE="$tmp_dir/app-initialized"
|
||||
|
||||
#We block on app-initialized so that when NGINX binds to $PORT
|
||||
#are app is ready for traffic.
|
||||
while [[ ! -f "$FILE" ]]
|
||||
do
|
||||
echo 'buildpack=nginx at=app-initialization'
|
||||
sleep 1
|
||||
done
|
||||
echo 'buildpack=nginx at=app-initialized'
|
||||
fi
|
||||
|
||||
#Start NGINX
|
||||
(
|
||||
#We expect nginx to run in foreground.
|
||||
#We also expect a socket to be at $tmp_dir/nginx.socket.
|
||||
echo 'buildpack=nginx at=nginx-start'
|
||||
$nginx -p . -c config/nginx.conf
|
||||
echo 'nginx' >$psmgr
|
||||
) &
|
||||
|
||||
#This read will block the process waiting on a msg to be put into the fifo.
|
||||
#If any of the processes defined above should exit,
|
||||
#a msg will be put into the fifo causing the read operation
|
||||
#to un-block. The process putting the msg into the fifo
|
||||
#will use it's process name as a msg so that we can print the offending
|
||||
#process to stdout.
|
||||
read exit_process <$psmgr
|
||||
echo "buildpack=nginx at=exit process=$exit_process"
|
||||
exit 1
|
||||
|
|
|
@ -20,4 +20,3 @@ development:
|
|||
test:
|
||||
<<: *defaults
|
||||
database: travis_test
|
||||
|
||||
|
|
76
config/mime.types
Normal file
76
config/mime.types
Normal file
|
@ -0,0 +1,76 @@
|
|||
|
||||
types {
|
||||
text/html html htm shtml;
|
||||
text/css css;
|
||||
text/xml xml;
|
||||
text/cache-manifest manifest appcache;
|
||||
image/gif gif;
|
||||
image/jpeg jpeg jpg;
|
||||
application/x-javascript js;
|
||||
application/atom+xml atom;
|
||||
application/rss+xml rss;
|
||||
|
||||
text/mathml mml;
|
||||
text/plain txt;
|
||||
text/vnd.sun.j2me.app-descriptor jad;
|
||||
text/vnd.wap.wml wml;
|
||||
text/x-component htc;
|
||||
|
||||
image/png png;
|
||||
image/tiff tif tiff;
|
||||
image/vnd.wap.wbmp wbmp;
|
||||
image/x-icon ico;
|
||||
image/x-jng jng;
|
||||
image/x-ms-bmp bmp;
|
||||
image/svg+xml svg;
|
||||
|
||||
application/java-archive jar war ear;
|
||||
application/mac-binhex40 hqx;
|
||||
application/msword doc;
|
||||
application/pdf pdf;
|
||||
application/postscript ps eps ai;
|
||||
application/rtf rtf;
|
||||
application/vnd.ms-excel xls;
|
||||
application/vnd.ms-powerpoint ppt;
|
||||
application/vnd.wap.wmlc wmlc;
|
||||
application/vnd.google-earth.kml+xml kml;
|
||||
application/vnd.google-earth.kmz kmz;
|
||||
application/x-7z-compressed 7z;
|
||||
application/x-cocoa cco;
|
||||
application/x-java-archive-diff jardiff;
|
||||
application/x-java-jnlp-file jnlp;
|
||||
application/x-makeself run;
|
||||
application/x-perl pl pm;
|
||||
application/x-pilot prc pdb;
|
||||
application/x-rar-compressed rar;
|
||||
application/x-redhat-package-manager rpm;
|
||||
application/x-sea sea;
|
||||
application/x-shockwave-flash swf;
|
||||
application/x-stuffit sit;
|
||||
application/x-tcl tcl tk;
|
||||
application/x-x509-ca-cert der pem crt;
|
||||
application/x-xpinstall xpi;
|
||||
application/xhtml+xml xhtml;
|
||||
application/zip zip;
|
||||
|
||||
application/octet-stream bin exe dll;
|
||||
application/octet-stream deb;
|
||||
application/octet-stream dmg;
|
||||
application/octet-stream eot;
|
||||
application/octet-stream iso img;
|
||||
application/octet-stream msi msp msm;
|
||||
|
||||
audio/midi mid midi kar;
|
||||
audio/mpeg mp3;
|
||||
audio/ogg ogg;
|
||||
audio/x-realaudio ra;
|
||||
|
||||
video/3gpp 3gpp 3gp;
|
||||
video/mpeg mpeg mpg;
|
||||
video/quicktime mov;
|
||||
video/x-flv flv;
|
||||
video/x-mng mng;
|
||||
video/x-ms-asf asx asf;
|
||||
video/x-ms-wmv wmv;
|
||||
video/x-msvideo avi;
|
||||
}
|
45
config/nginx.conf.erb
Normal file
45
config/nginx.conf.erb
Normal file
|
@ -0,0 +1,45 @@
|
|||
daemon off;
|
||||
#Heroku dynos have at least 4 cores.
|
||||
worker_processes <%= ENV['NGINX_WORKERS'] || ENV['WEB_CONCURRENCY'] || 4 %>;
|
||||
|
||||
events {
|
||||
<% if `uname` != "Darwin\n" %>use epoll;<% end %>
|
||||
accept_mutex on;
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
gzip on;
|
||||
gzip_comp_level 2;
|
||||
gzip_min_length 512;
|
||||
|
||||
server_tokens off;
|
||||
|
||||
log_format l2met 'measure#nginx.service=$request_time request_id=$http_x_request_id';
|
||||
access_log logs/nginx/access.log l2met;
|
||||
error_log logs/nginx/error.log;
|
||||
|
||||
include mime.types;
|
||||
default_type application/octet-stream;
|
||||
sendfile on;
|
||||
|
||||
#Must read the body in 5 seconds.
|
||||
client_body_timeout 5;
|
||||
|
||||
upstream app_server {
|
||||
server unix:<%= ENV["tmp_dir"] %>/nginx.socket fail_timeout=0;
|
||||
}
|
||||
|
||||
server {
|
||||
listen <%= ENV["PORT"] %>;
|
||||
server_name _;
|
||||
keepalive_timeout 5;
|
||||
|
||||
location / {
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_redirect off;
|
||||
proxy_pass http://app_server;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,8 +2,8 @@ root = File.expand_path('../..', __FILE__)
|
|||
|
||||
rackup "#{root}/config.ru"
|
||||
|
||||
bind 'unix:///tmp/nginx.socket'
|
||||
|
||||
tmp_dir = ENV.fetch("tmp_dir", "/tmp")
|
||||
bind "unix://#{tmp_dir}/nginx.socket"
|
||||
environment ENV['RACK_ENV'] || 'development'
|
||||
|
||||
threads 0, 16
|
||||
|
|
7
config/ruby_config.sh
Normal file
7
config/ruby_config.sh
Normal file
|
@ -0,0 +1,7 @@
|
|||
#!/bin/bash
|
||||
export RUBY_HEAP_MIN_SLOTS=800000
|
||||
export RUBY_GC_HEAP_INIT_SLOTS=$RUBY_HEAP_MIN_SLOTS
|
||||
export RUBY_GC_MALLOC_LIMIT=59000000
|
||||
export RUBY_HEAP_SLOTS_INCREMENT=10000
|
||||
export RUBY_HEAP_SLOTS_GROWTH_FACTOR=1
|
||||
export RUBY_HEAP_FREE_MIN=100000
|
|
@ -1,19 +1,16 @@
|
|||
# http://michaelvanrooijen.com/articles/2011/06/01-more-concurrency-on-a-single-heroku-dyno-with-the-new-celadon-cedar-stack/
|
||||
|
||||
worker_processes 4 # amount of unicorn workers to spin up
|
||||
timeout 30 # restarts workers that hang for 15 seconds
|
||||
worker_processes Integer(ENV.fetch('WEB_CONCURRENCY')) # amount of unicorn workers to spin up
|
||||
timeout 30 # restarts workers that hang for 30 seconds
|
||||
|
||||
listen '/tmp/nginx.socket', backlog: 1024
|
||||
tmp_dir = ENV.fetch("tmp_dir", "/tmp")
|
||||
listen File.expand_path("nginx.socket", tmp_dir), backlog: 1024
|
||||
|
||||
require 'fileutils'
|
||||
before_fork do |server,worker|
|
||||
FileUtils.touch('/tmp/app-initialized')
|
||||
end
|
||||
before_fork do |server, worker|
|
||||
# preload travis so we can have copy on write
|
||||
require 'travis/api/app'
|
||||
|
||||
before_exec do |server|
|
||||
ENV['RUBY_HEAP_MIN_SLOTS']=800000
|
||||
ENV['RUBY_GC_MALLOC_LIMIT']=59000000
|
||||
ENV['RUBY_HEAP_SLOTS_INCREMENT']=10000
|
||||
ENV['RUBY_HEAP_SLOTS_GROWTH_FACTOR']=1
|
||||
ENV['RUBY_HEAP_FREE_MIN']=100000
|
||||
# signal to nginx we're ready
|
||||
FileUtils.touch("#{tmp_dir}/app-initialized")
|
||||
end
|
||||
|
|
BIN
heroku-buildpack-sigsci.tgz
Normal file
BIN
heroku-buildpack-sigsci.tgz
Normal file
Binary file not shown.
30
lib/active_record_postgres_variables.rb
Normal file
30
lib/active_record_postgres_variables.rb
Normal file
|
@ -0,0 +1,30 @@
|
|||
# This backports support for the :variables option on postgres database details from ActiveRecord 4 to ActiveRecord 3.
|
||||
require 'active_record'
|
||||
|
||||
if ActiveRecord::VERSION::MAJOR < 4
|
||||
require 'active_record/connection_adapters/postgresql_adapter'
|
||||
|
||||
module ActiveRecordPostgresVariables
|
||||
def configure_connection
|
||||
result = super
|
||||
set_variables
|
||||
result
|
||||
end
|
||||
|
||||
def set_variables
|
||||
return unless variables = @config[:variables]
|
||||
|
||||
# copied from AR 4.2.1
|
||||
variables.map do |k, v|
|
||||
if v == ':default' || v == :default
|
||||
# Sets the value to the global or compile default
|
||||
execute("SET SESSION #{k} TO DEFAULT", 'SCHEMA')
|
||||
elsif !v.nil?
|
||||
execute("SET SESSION #{k} TO #{quote(v)}", 'SCHEMA')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(ActiveRecordPostgresVariables)
|
||||
end
|
67
lib/travis.rb
Normal file
67
lib/travis.rb
Normal file
|
@ -0,0 +1,67 @@
|
|||
require 'pusher'
|
||||
require 'travis/support'
|
||||
require 'travis/support/database'
|
||||
require 'travis/redis_pool'
|
||||
require 'travis/errors'
|
||||
|
||||
module Travis
|
||||
class << self
|
||||
def services=(services)
|
||||
@services = services
|
||||
end
|
||||
|
||||
def services
|
||||
@services ||= Travis::Services
|
||||
end
|
||||
end
|
||||
|
||||
require 'travis/model'
|
||||
require 'travis/task'
|
||||
require 'travis/event'
|
||||
require 'travis/api/serialize'
|
||||
require 'travis/config/defaults'
|
||||
require 'travis/features'
|
||||
require 'travis/github'
|
||||
require 'travis/notification'
|
||||
require 'travis/services'
|
||||
|
||||
class UnknownRepository < StandardError; end
|
||||
class GithubApiError < StandardError; end
|
||||
class AdminMissing < StandardError; end
|
||||
class RepositoryMissing < StandardError; end
|
||||
class LogAlreadyRemoved < StandardError; end
|
||||
class AuthorizationDenied < StandardError; end
|
||||
class JobUnfinished < StandardError; end
|
||||
|
||||
class << self
|
||||
def setup(options = {})
|
||||
@config = Config.load(*options[:configs])
|
||||
@redis = Travis::RedisPool.new(config.redis.to_h)
|
||||
|
||||
Travis.logger.info('Setting up Travis::Core')
|
||||
|
||||
Github.setup
|
||||
Services.register
|
||||
Github::Services.register
|
||||
end
|
||||
|
||||
attr_accessor :redis, :config
|
||||
|
||||
def pusher
|
||||
@pusher ||= ::Pusher.tap do |pusher|
|
||||
pusher.app_id = config.pusher.app_id
|
||||
pusher.key = config.pusher.key
|
||||
pusher.secret = config.pusher.secret
|
||||
pusher.scheme = config.pusher.scheme if config.pusher.scheme
|
||||
pusher.host = config.pusher.host if config.pusher.host
|
||||
pusher.port = config.pusher.port if config.pusher.port
|
||||
end
|
||||
end
|
||||
|
||||
def states_cache
|
||||
@states_cache ||= Travis::StatesCache.new
|
||||
end
|
||||
end
|
||||
|
||||
setup
|
||||
end
|
|
@ -1,26 +1,40 @@
|
|||
# these things need to go first
|
||||
require 'conditional_skylight'
|
||||
require 'active_record_postgres_variables'
|
||||
|
||||
# now actually load travis
|
||||
require 'travis'
|
||||
require 'travis/amqp'
|
||||
require 'travis/model'
|
||||
require 'travis/support/amqp'
|
||||
require 'travis/states_cache'
|
||||
require 'rack'
|
||||
require 'rack/protection'
|
||||
require 'rack/contrib'
|
||||
require 'rack/contrib/config'
|
||||
require 'rack/contrib/jsonp'
|
||||
require 'rack/contrib/post_body_content_type_parser'
|
||||
require 'dalli'
|
||||
require 'memcachier'
|
||||
require 'rack/cache'
|
||||
require 'rack/attack'
|
||||
require 'travis/api/attack'
|
||||
require 'active_record'
|
||||
require 'redis'
|
||||
require 'gh'
|
||||
require 'raven'
|
||||
require 'raven/integrations/rack'
|
||||
require 'sidekiq'
|
||||
require 'metriks/reporter/logger'
|
||||
require 'metriks/librato_metrics_reporter'
|
||||
require 'travis/support/log_subscriber/active_record_metrics'
|
||||
require 'fileutils'
|
||||
require 'securerandom'
|
||||
|
||||
module Travis::Api
|
||||
end
|
||||
|
||||
require 'travis/api/app/endpoint'
|
||||
require 'travis/api/app/middleware'
|
||||
require 'travis/api/instruments'
|
||||
require 'travis/api/v2/http'
|
||||
require 'travis/api/serialize/v2'
|
||||
require 'travis/api/v3'
|
||||
require 'travis/api/app/stack_instrumentation'
|
||||
require 'travis/api/app/error_handling'
|
||||
|
@ -68,34 +82,27 @@ module Travis::Api
|
|||
end
|
||||
|
||||
def self.deploy_sha
|
||||
@deploy_sha ||= File.exist?(deploy_sha_path) ? File.read(deploy_sha_path)[0..7] : 'deploy-sha'
|
||||
end
|
||||
|
||||
def self.deploy_sha_path
|
||||
File.expand_path('../../../../.deploy-sha', __FILE__)
|
||||
@deploy_sha ||= ENV['HEROKU_SLUG_COMMIT'] || SecureRandom.hex(5)
|
||||
end
|
||||
|
||||
attr_accessor :app
|
||||
|
||||
def initialize
|
||||
@app = Rack::Builder.app do
|
||||
# if stackprof = ENV['STACKPROF']
|
||||
# require 'stackprof'
|
||||
# modes = ['wall', 'cpu', 'object', 'custom']
|
||||
# mode = modes.include?(stackprof) ? stackprof.to_sym : :cpu
|
||||
# Travis.logger.info "Setting up profiler: #{mode}"
|
||||
# use StackProf::Middleware, enabled: true, save_every: 1, mode: mode
|
||||
# end
|
||||
|
||||
extend StackInstrumentation
|
||||
use Travis::Api::App::Middleware::Skylight
|
||||
use(Rack::Config) { |env| env['metriks.request.start'] ||= Time.now.utc }
|
||||
|
||||
Rack::Utils::HTTP_STATUS_CODES[420] = "Enhance Your Calm"
|
||||
use Rack::Attack
|
||||
Rack::Attack.blacklist('block client requesting ruby builds') do |req|
|
||||
req.ip == "130.15.4.210"
|
||||
end
|
||||
|
||||
Rack::Attack.blacklisted_response = lambda do |env|
|
||||
[ 420, {}, ['Enhance Your Calm']]
|
||||
end
|
||||
|
||||
use Travis::Api::App::Cors # if Travis.env == 'development' ???
|
||||
use Raven::Rack if Travis.env == 'production' || Travis.env == 'staging'
|
||||
use Rack::Protection::PathTraversal
|
||||
use Raven::Rack if Travis::Api::App.use_monitoring?
|
||||
use Rack::SSL if Endpoint.production?
|
||||
use ActiveRecord::ConnectionAdapters::ConnectionManagement
|
||||
use ActiveRecord::QueryCache
|
||||
|
@ -120,7 +127,9 @@ module Travis::Api
|
|||
use Travis::Api::App::Middleware::Logging
|
||||
use Travis::Api::App::Middleware::ScopeCheck
|
||||
use Travis::Api::App::Middleware::UserAgentTracker
|
||||
use Travis::Api::App::Middleware::Metriks
|
||||
|
||||
# make sure this is below ScopeCheck so we have the token
|
||||
use Rack::Attack if Endpoint.production? and not Travis.config.enterprise
|
||||
|
||||
# if this is a v3 API request, ignore everything after
|
||||
use Travis::API::V3::OptIn
|
||||
|
@ -128,6 +137,9 @@ module Travis::Api
|
|||
# rewrite should come after V3 hook
|
||||
use Travis::Api::App::Middleware::Rewrite
|
||||
|
||||
# v3 has its own metriks
|
||||
use Travis::Api::App::Middleware::Metriks
|
||||
|
||||
SettingsEndpoint.subclass :env_vars
|
||||
if Travis.config.endpoints.ssh_key
|
||||
SingletonSettingsEndpoint.subclass :ssh_key
|
||||
|
@ -164,14 +176,13 @@ module Travis::Api
|
|||
|
||||
def self.setup!
|
||||
setup_travis
|
||||
load_endpoints
|
||||
setup_endpoints
|
||||
@setup = true
|
||||
end
|
||||
|
||||
def self.setup_travis
|
||||
Travis::Async.enabled = true
|
||||
Travis::Amqp.config = Travis.config.amqp
|
||||
Travis::Amqp.setup(Travis.config.amqp)
|
||||
|
||||
setup_database_connections
|
||||
|
||||
|
@ -181,17 +192,21 @@ module Travis::Api
|
|||
end
|
||||
end
|
||||
|
||||
if use_monitoring? and not console?
|
||||
if use_monitoring? && !console?
|
||||
setup_monitoring
|
||||
end
|
||||
end
|
||||
|
||||
def self.setup_database_connections
|
||||
Travis.config.database.variables ||= {}
|
||||
Travis.config.database.variables.application_name ||= ["api", Travis.env, ENV['DYNO']].compact.join(?-)
|
||||
Travis::Database.connect
|
||||
|
||||
if Travis.config.logs_database
|
||||
Log.establish_connection 'logs_database'
|
||||
Log::Part.establish_connection 'logs_database'
|
||||
pool_size = ENV['DATABASE_POOL_SIZE']
|
||||
Travis.config.logs_database[:pool] = pool_size.to_i if pool_size
|
||||
|
||||
Travis::LogsModel.establish_connection 'logs_database'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -203,11 +218,6 @@ module Travis::Api
|
|||
Travis::Metrics.setup
|
||||
end
|
||||
|
||||
def self.load_endpoints
|
||||
Dir.glob("#{__dir__}/app/middleware/*.rb").each { |f| require f[%r[(?<=lib/).+(?=\.rb$)]] }
|
||||
Dir.glob("#{__dir__}/app/endpoint/*.rb").each { |f| require f[%r[(?<=lib/).+(?=\.rb$)]] }
|
||||
end
|
||||
|
||||
def self.setup_endpoints
|
||||
Base.subclasses.each(&:setup)
|
||||
end
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
require 'travis/api/app'
|
||||
require 'sinatra/base'
|
||||
require 'mustermann'
|
||||
require 'travis/api/app'
|
||||
require 'travis/api/app/extensions'
|
||||
require 'travis/api/app/helpers'
|
||||
|
||||
class Travis::Api::App
|
||||
# Superclass for any endpoint and middleware.
|
||||
|
|
|
@ -15,6 +15,11 @@ class Travis::Api::App
|
|||
options // do
|
||||
headers['Access-Control-Allow-Methods'] = "HEAD, GET, POST, PATCH, PUT, DELETE"
|
||||
headers['Access-Control-Allow-Headers'] = "Content-Type, Authorization, Accept, If-None-Match, If-Modified-Since, X-User-Agent, Travis-API-Version"
|
||||
|
||||
# cache OPTIONS for 24 hours to avoid excessive preflight requests and speed up access
|
||||
# browsers might still limit this value to 10 minutes, see caveats
|
||||
# http://stackoverflow.com/a/12021982
|
||||
headers['Access-Control-Max-Age'] = "86400"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
require 'travis/api/app'
|
||||
require 'addressable/uri'
|
||||
require 'active_record/base'
|
||||
require 'travis/api/app'
|
||||
require 'travis/api/app/base'
|
||||
|
||||
class Travis::Api::App
|
||||
# Superclass for HTTP endpoints. Takes care of prefixing.
|
||||
|
@ -48,3 +49,23 @@ class Travis::Api::App
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
require 'travis/api/app/endpoint/accounts'
|
||||
require 'travis/api/app/endpoint/authorization'
|
||||
require 'travis/api/app/endpoint/branches'
|
||||
require 'travis/api/app/endpoint/broadcasts'
|
||||
require 'travis/api/app/endpoint/builds'
|
||||
require 'travis/api/app/endpoint/documentation'
|
||||
require 'travis/api/app/endpoint/endpoints'
|
||||
require 'travis/api/app/endpoint/env_vars'
|
||||
require 'travis/api/app/endpoint/home'
|
||||
require 'travis/api/app/endpoint/hooks'
|
||||
require 'travis/api/app/endpoint/jobs'
|
||||
require 'travis/api/app/endpoint/lint'
|
||||
require 'travis/api/app/endpoint/logs'
|
||||
require 'travis/api/app/endpoint/repos'
|
||||
require 'travis/api/app/endpoint/requests'
|
||||
require 'travis/api/app/endpoint/setting_endpoint'
|
||||
require 'travis/api/app/endpoint/singleton_settings_endpoint'
|
||||
require 'travis/api/app/endpoint/uptime'
|
||||
require 'travis/api/app/endpoint/users'
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
require 'travis/api/app'
|
||||
require 'addressable/uri'
|
||||
require 'faraday'
|
||||
require 'securerandom'
|
||||
require 'customerio'
|
||||
require 'travis/api/app'
|
||||
require 'travis/github/education'
|
||||
require 'travis/github/oauth'
|
||||
|
||||
class Travis::Api::App
|
||||
class Endpoint
|
||||
|
@ -78,6 +81,7 @@ class Travis::Api::App
|
|||
#
|
||||
# * **github_token**: GitHub token for checking authorization (required)
|
||||
post '/github' do
|
||||
check_agent
|
||||
unless params[:github_token]
|
||||
halt 422, { "error" => "Must pass 'github_token' parameter" }
|
||||
end
|
||||
|
@ -94,6 +98,7 @@ class Travis::Api::App
|
|||
# * **redirect_uri**: URI to redirect to after handshake.
|
||||
get '/handshake' do
|
||||
handshake do |user, token, redirect_uri|
|
||||
|
||||
if target_ok? redirect_uri
|
||||
content_type :html
|
||||
data = { user: user, token: token, uri: redirect_uri }
|
||||
|
@ -109,7 +114,7 @@ class Travis::Api::App
|
|||
# access token and user payload to the parent window via postMessage.
|
||||
#
|
||||
# However, the endpoint to send the payload to has to be explicitely
|
||||
# whitelisted in production, as this is endpoint is only meant to be used
|
||||
# safelisted in production, as this is endpoint is only meant to be used
|
||||
# with the official Travis CI client at the moment.
|
||||
#
|
||||
# Example usage:
|
||||
|
@ -145,8 +150,46 @@ class Travis::Api::App
|
|||
|
||||
private
|
||||
|
||||
def allowed_agents
|
||||
@allowed_agents ||= redis.smembers('auth_agents')
|
||||
end
|
||||
|
||||
def check_agent
|
||||
return if settings.test? or allowed_agents.empty?
|
||||
return if allowed_agents.any? { |a| request.user_agent.to_s.start_with? a }
|
||||
halt 403, "you are currently not allowed to perform this request. please contact support@travis-ci.com."
|
||||
end
|
||||
|
||||
# update first login date if not set
|
||||
def update_first_login(user)
|
||||
unless user.first_logged_in_at
|
||||
user.update_attributes(first_logged_in_at: Time.now)
|
||||
end
|
||||
end
|
||||
|
||||
def update_customerio(user)
|
||||
return unless Travis.config.customerio.site_id
|
||||
|
||||
# send event to customer.io
|
||||
payload = {
|
||||
:id => user.id,
|
||||
:name => user.name,
|
||||
:login => user.login,
|
||||
:email => primary_email_for_user(user.github_oauth_token),
|
||||
:created_at => user.created_at.to_i,
|
||||
:github_id => user.github_id,
|
||||
:education => user.education,
|
||||
:first_logged_in_at => user.first_logged_in_at.to_i,
|
||||
:travis_domain => Travis.config.client_domain
|
||||
}
|
||||
|
||||
customerio.identify(payload)
|
||||
rescue StandardError => e
|
||||
Travis.logger.error "Could not update Customer.io for User: #{user.id}:#{user.login} with message:#{e.message}"
|
||||
end
|
||||
|
||||
def serialize_user(user)
|
||||
rendered = Travis::Api.data(user, version: :v2)
|
||||
rendered = Travis::Api::Serialize.data(user, version: :v2)
|
||||
rendered['user'].merge('token' => user.tokens.first.try(:token).to_s)
|
||||
end
|
||||
|
||||
|
@ -174,6 +217,8 @@ class Travis::Api::App
|
|||
user = user_for_github_token(github_token)
|
||||
token = generate_token(user: user, app_id: 0)
|
||||
payload = params[:state].split(":::", 2)[1]
|
||||
update_first_login(user)
|
||||
update_customerio(user)
|
||||
yield serialize_user(user), token, payload
|
||||
else
|
||||
values[:state] = create_state
|
||||
|
@ -183,6 +228,7 @@ class Travis::Api::App
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
def create_state
|
||||
state = SecureRandom.urlsafe_base64(16)
|
||||
redis.sadd('github:states', state)
|
||||
|
@ -212,6 +258,7 @@ class Travis::Api::App
|
|||
super
|
||||
|
||||
@user = ::User.find_by_github_id(data['id'])
|
||||
|
||||
end
|
||||
|
||||
def info(attributes = {})
|
||||
|
@ -243,8 +290,11 @@ class Travis::Api::App
|
|||
user.update_attributes info
|
||||
else
|
||||
self.user = ::User.create! info
|
||||
Travis.run_service(:sync_user, user)
|
||||
end
|
||||
|
||||
Travis::Github::Oauth.update_scopes(user) # unless Travis.env == 'test'
|
||||
|
||||
nullify_logins(user.github_id, user.login)
|
||||
end
|
||||
|
||||
|
@ -296,7 +346,7 @@ class Travis::Api::App
|
|||
end
|
||||
|
||||
def acceptable?(scopes, lossy = false)
|
||||
User::Oauth.wanted_scopes.all? do |scope|
|
||||
Travis::Github::Oauth.wanted_scopes.all? do |scope|
|
||||
acceptable_scopes_for(scope, lossy).any? { |s| scopes.include? s }
|
||||
end
|
||||
end
|
||||
|
@ -342,6 +392,15 @@ class Travis::Api::App
|
|||
def allowed_https_targets
|
||||
@allowed_https_targets ||= Travis.config.auth.target_origin.to_s.split(',')
|
||||
end
|
||||
|
||||
def primary_email_for_user(oauth_token)
|
||||
# check for the users primary email address (we don't store this info)
|
||||
GH.with(token: oauth_token, client_id: nil) { GH['user/emails'] }.select { |e| e['primary'] }.first['email']
|
||||
end
|
||||
|
||||
def customerio
|
||||
Customerio::Client.new(Travis.config.customerio.site_id, Travis.config.customerio.api_key, :json => true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -350,7 +409,7 @@ __END__
|
|||
|
||||
@@ invalid_target
|
||||
<script>
|
||||
console.log('refusing to send a token to <%= target_origin.inspect %>, not whitelisted!');
|
||||
console.log('refusing to send a token to <%= target_origin.inspect %>, not safelisted!');
|
||||
</script>
|
||||
|
||||
@@ common
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
require 'travis/api/app'
|
||||
require 'travis/api/workers/build_cancellation'
|
||||
require 'travis/api/workers/build_restart'
|
||||
require 'travis/api/enqueue/services/restart_model'
|
||||
require 'travis/api/enqueue/services/cancel_model'
|
||||
|
||||
class Travis::Api::App
|
||||
class Endpoint
|
||||
|
@ -20,7 +22,8 @@ class Travis::Api::App
|
|||
post '/:id/cancel' do
|
||||
Metriks.meter("api.request.cancel_build").mark
|
||||
|
||||
service = self.service(:cancel_build, params.merge(source: 'api'))
|
||||
service = Travis::Enqueue::Services::CancelModel.new(current_user, { build_id: params[:id] })
|
||||
|
||||
if !service.authorized?
|
||||
json = { error: {
|
||||
message: "You don't have access to cancel build(#{params[:id]})"
|
||||
|
@ -39,7 +42,9 @@ class Travis::Api::App
|
|||
status 422
|
||||
respond_with json
|
||||
else
|
||||
Travis::Sidekiq::BuildCancellation.perform_async(id: params[:id], user_id: current_user.id, source: 'api')
|
||||
payload = { id: params[:id], user_id: current_user.id, source: 'api' }
|
||||
|
||||
service.push("build:cancel", payload)
|
||||
|
||||
Metriks.meter("api.request.cancel_build.success").mark
|
||||
status 204
|
||||
|
@ -48,16 +53,18 @@ class Travis::Api::App
|
|||
|
||||
post '/:id/restart' do
|
||||
Metriks.meter("api.request.restart_build").mark
|
||||
service = Travis::Enqueue::Services::RestartModel.new(current_user, build_id: params[:id])
|
||||
|
||||
service = self.service(:reset_model, build_id: params[:id])
|
||||
if !service.accept?
|
||||
result = if !service.accept?
|
||||
status 400
|
||||
result = false
|
||||
false
|
||||
else
|
||||
Travis::Sidekiq::BuildRestart.perform_async(id: params[:id], user_id: current_user.id)
|
||||
payload = { id: params[:id], user_id: current_user.id }
|
||||
service.push("build:restart", payload)
|
||||
status 202
|
||||
result = true
|
||||
true
|
||||
end
|
||||
|
||||
respond_with(result: result, flash: service.messages)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,7 +11,7 @@ class Travis::Api::App
|
|||
host: host,
|
||||
shorten_host: Travis.config.shorten_host,
|
||||
assets: Travis.config.assets,
|
||||
pusher: (Travis.config.pusher_ws || Travis.config.pusher || {}).to_hash.slice(:scheme, :host, :port, :path, :key),
|
||||
pusher: (Travis.config.pusher_ws || Travis.config.pusher || {}).to_hash.slice(:scheme, :host, :port, :path, :key, :secure, :private),
|
||||
github: { api_url: GH.current.api_host.to_s, scopes: Travis.config.oauth2.try(:scope).to_s.split(?,) }
|
||||
|
||||
# Landing point. Redirects web browsers to [API documentation](#/docs/).
|
||||
|
@ -49,6 +49,18 @@ class Travis::Api::App
|
|||
get '/config' do
|
||||
{ config: settings.client_config }
|
||||
end
|
||||
|
||||
deploy_sha = File.read(".deploy-sha") if File.exist?(".deploy-sha")
|
||||
sys_info = {
|
||||
web_concurrency: ENV['WEB_CONCURRENCY'],
|
||||
ulimit: `echo "ulimit -u" | bash`.to_i,
|
||||
dyno: ENV['DYNO'],
|
||||
deploy_sha: deploy_sha
|
||||
}
|
||||
|
||||
get '/sysinfo' do
|
||||
sys_info
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
require 'travis/api/app'
|
||||
require 'travis/api/workers/job_cancellation'
|
||||
require 'travis/api/workers/job_restart'
|
||||
require 'travis/api/enqueue/services/restart_model'
|
||||
require 'travis/api/enqueue/services/cancel_model'
|
||||
|
||||
class Travis::Api::App
|
||||
class Endpoint
|
||||
|
@ -27,7 +29,8 @@ class Travis::Api::App
|
|||
post '/:id/cancel' do
|
||||
Metriks.meter("api.request.cancel_job").mark
|
||||
|
||||
service = self.service(:cancel_job, params.merge(source: 'api'))
|
||||
service = Travis::Enqueue::Services::CancelModel.new(current_user, { job_id: params[:id] })
|
||||
|
||||
if !service.authorized?
|
||||
json = { error: {
|
||||
message: "You don't have access to cancel job(#{params[:id]})"
|
||||
|
@ -46,7 +49,8 @@ class Travis::Api::App
|
|||
status 422
|
||||
respond_with json
|
||||
else
|
||||
Travis::Sidekiq::JobCancellation.perform_async(id: params[:id], user_id: current_user.id, source: 'api')
|
||||
payload = { id: params[:id], user_id: current_user.id, source: 'api' }
|
||||
service.push("job:cancel", payload)
|
||||
|
||||
Metriks.meter("api.request.cancel_job.success").mark
|
||||
status 204
|
||||
|
@ -56,15 +60,18 @@ class Travis::Api::App
|
|||
post '/:id/restart' do
|
||||
Metriks.meter("api.request.restart_job").mark
|
||||
|
||||
service = self.service(:reset_model, job_id: params[:id])
|
||||
if !service.accept?
|
||||
service = Travis::Enqueue::Services::RestartModel.new(current_user, { job_id: params[:id] })
|
||||
|
||||
result = if !service.accept?
|
||||
status 400
|
||||
result = false
|
||||
false
|
||||
else
|
||||
Travis::Sidekiq::JobRestart.perform_async(id: params[:id], user_id: current_user.id)
|
||||
payload = {id: params[:id], user_id: current_user.id}
|
||||
service.push("job:restart", payload)
|
||||
status 202
|
||||
result = true
|
||||
true
|
||||
end
|
||||
|
||||
respond_with(result: result, flash: service.messages)
|
||||
end
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ class Travis::Api::App
|
|||
# json(:repositories)
|
||||
get '/' do
|
||||
prefer_follower do
|
||||
params['ids'] = params['ids'].split(',') if params['ids'].respond_to?(:split)
|
||||
respond_with service(:find_repos, params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,19 +1,10 @@
|
|||
require 'travis/api/app'
|
||||
require 'travis/api/app/services/schedule_request'
|
||||
require 'travis/api/enqueue/services/restart_model'
|
||||
|
||||
class Travis::Api::App
|
||||
class Endpoint
|
||||
class Requests < Endpoint
|
||||
post '/', scope: :private do
|
||||
if params[:request] && params[:request][:repository]
|
||||
respond_with service(:schedule_request, params[:request])
|
||||
else
|
||||
# DEPRECATED: this will be removed by 1st of December
|
||||
Metriks.meter("api.request.restart").mark
|
||||
respond_with service(:reset_model, params)
|
||||
end
|
||||
end
|
||||
|
||||
get '/' do
|
||||
begin
|
||||
respond_with(service(:find_requests, params).run)
|
||||
|
@ -26,7 +17,28 @@ class Travis::Api::App
|
|||
get '/:id' do
|
||||
respond_with service(:find_request, params)
|
||||
end
|
||||
|
||||
post '/', scope: :private do
|
||||
if params[:request] && params[:request][:repository]
|
||||
status 404
|
||||
else
|
||||
# DEPRECATED: this will be removed by 1st of December
|
||||
#
|
||||
# TODO It seems this endpoint is still in use, quite a bit:
|
||||
# https://metrics.librato.com/s/metrics/api.request.restart?duration=2419200&q=api.request.restart
|
||||
#
|
||||
# I think we need to properly deprecate this by publishing a blog post.
|
||||
Metriks.meter("api.request.restart").mark
|
||||
service = Travis::Enqueue::Services::RestartModel.new(current_user, params)
|
||||
params[:user_id] = service.target.repository.owner.id
|
||||
|
||||
type = params[:build_id] ? 'build' : 'job'
|
||||
params[:id] = params[:build_id] || params[:job_id]
|
||||
|
||||
service.push("#{type}:restart", params)
|
||||
respond_with(result: true, flash: service.messages)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ class Travis::Api::App
|
|||
Thread.new do
|
||||
loop do
|
||||
begin
|
||||
Raven.send queue.pop
|
||||
Raven.send_event queue.pop
|
||||
rescue Exception => e
|
||||
puts e.message, e.backtrace
|
||||
end
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
require 'travis/api/app'
|
||||
|
||||
class Travis::Api::App
|
||||
# Namespace for Sinatra extensions.
|
||||
module Extensions
|
||||
Dir.glob("#{__dir__}/extensions/*.rb").each { |f| require f[%r[(?<=lib/).+(?=\.rb$)]] }
|
||||
end
|
||||
end
|
||||
require 'travis/api/app/extensions/expose_pattern'
|
||||
require 'travis/api/app/extensions/scoping'
|
||||
require 'travis/api/app/extensions/smart_constants'
|
||||
require 'travis/api/app/extensions/subclass_tracker'
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
require 'travis/api/app'
|
||||
|
||||
class Travis::Api::App
|
||||
# Namespace for helpers.
|
||||
module Helpers
|
||||
Dir.glob("#{__dir__}/helpers/*.rb").each { |f| require f[%r[(?<=lib/).+(?=\.rb$)]] }
|
||||
end
|
||||
end
|
||||
require 'travis/api/app/helpers/accept'
|
||||
require 'travis/api/app/helpers/current_user'
|
||||
require 'travis/api/app/helpers/db_follower'
|
||||
require 'travis/api/app/helpers/flash'
|
||||
require 'travis/api/app/helpers/mime_types'
|
||||
require 'travis/api/app/helpers/respond_with'
|
||||
|
|
|
@ -53,6 +53,8 @@ class Travis::Api::App
|
|||
if params
|
||||
params = Hash[*params.split(';').map { |p| p.scan /(#{TOKEN})=(#{TOKEN})/ }.flatten]
|
||||
quality = params.delete('q').to_f if params['q']
|
||||
else
|
||||
params = {}
|
||||
end
|
||||
|
||||
if subtype =~ HEADER_FORMAT
|
||||
|
@ -82,7 +84,7 @@ class Travis::Api::App
|
|||
end
|
||||
|
||||
def accept_version
|
||||
@accept_version ||= request.accept.join =~ HEADER_FORMAT && "v#{$1}" || DEFAULT_VERSION
|
||||
@accept_version ||= accept_entries.map(&:version).compact.first || DEFAULT_VERSION
|
||||
end
|
||||
|
||||
def accept_format
|
||||
|
|
|
@ -3,5 +3,11 @@ require 'travis/api/app'
|
|||
class Travis::Api::App
|
||||
# Superclass for all middleware.
|
||||
class Middleware < Base
|
||||
require 'travis/api/app/middleware/logging'
|
||||
require 'travis/api/app/middleware/metriks'
|
||||
require 'travis/api/app/middleware/rewrite'
|
||||
require 'travis/api/app/middleware/scope_check'
|
||||
require 'travis/api/app/middleware/skylight'
|
||||
require 'travis/api/app/middleware/user_agent_tracker'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -37,7 +37,7 @@ class Travis::Api::App
|
|||
end
|
||||
|
||||
def mark_travis(agent)
|
||||
command = agent.application.comment.detect { |c| c.start_with? "command " }
|
||||
command = agent.application.comment.detect { |c| c.start_with? "command " } if agent.application.comment
|
||||
|
||||
if command
|
||||
mark(:cli, :version, agent.version)
|
||||
|
|
|
@ -4,15 +4,15 @@ module Travis::Api::App::Responders
|
|||
class Atom < Base
|
||||
ATOM_FEED_ERB = ERB.new <<-EOF
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
|
||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||
|
||||
|
||||
<title><%= resource.first.repository.slug %> Builds</title>
|
||||
<link href="<%= endpoint.url %>" type="application/atom+xml" rel = "self" />
|
||||
<id>repo:<%= resource.first.repository.id %></id>
|
||||
<rights>Copyright (c) <%= DateTime.now.strftime("%Y") %> Travis CI GmbH</rights>
|
||||
<updated><%= DateTime.now.rfc3339 %></updated>
|
||||
|
||||
|
||||
<% resource.each do |build| %>
|
||||
<entry>
|
||||
<title><%= build.repository.slug %> Build #<%= build.number %></title>
|
||||
|
@ -21,7 +21,7 @@ module Travis::Api::App::Responders
|
|||
<updated><%= ::DateTime.parse(build.updated_at.to_s).rfc3339 %></updated>
|
||||
<summary type="html">
|
||||
<p>
|
||||
<%= build.commit.message.encode(:xml => :text) %> (<%= build.commit.committer_name %>)
|
||||
<%= build.commit.message.encode(:xml => :text) if build.commit.message %> (<%= build.commit.committer_name %>)
|
||||
<br/><br/>
|
||||
State: <%= build.state %>
|
||||
<br/>
|
||||
|
@ -36,7 +36,7 @@ module Travis::Api::App::Responders
|
|||
</author>
|
||||
</entry>
|
||||
<% end %>
|
||||
|
||||
|
||||
</feed>
|
||||
EOF
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
require 'travis/api/serialize'
|
||||
|
||||
class Travis::Api::App
|
||||
module Responders
|
||||
class Json < Base
|
||||
|
@ -46,7 +48,7 @@ class Travis::Api::App
|
|||
if defined?(@builder)
|
||||
@builder
|
||||
else
|
||||
@builder = Travis::Api.builder(resource, { :version => version }.merge(options))
|
||||
@builder = Travis::Api::Serialize.builder(resource, { :version => version }.merge(options))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -8,7 +8,15 @@ class Travis::Api::App
|
|||
register :schedule_request
|
||||
|
||||
def run
|
||||
repo && active? ? schedule_request : not_found
|
||||
if repo.nil?
|
||||
not_found
|
||||
elsif !active?
|
||||
not_active
|
||||
elsif throttle.throttled?
|
||||
throttled
|
||||
else
|
||||
schedule_request
|
||||
end
|
||||
end
|
||||
|
||||
def messages
|
||||
|
@ -29,6 +37,16 @@ class Travis::Api::App
|
|||
:not_found
|
||||
end
|
||||
|
||||
def not_active
|
||||
messages << { error: "Repository #{slug} not active." }
|
||||
:not_active
|
||||
end
|
||||
|
||||
def throttled
|
||||
messages << { error: "Repository #{slug} throttled." }
|
||||
:throttled
|
||||
end
|
||||
|
||||
def active?
|
||||
Travis::Features.owner_active?(:request_create, repo.owner)
|
||||
end
|
||||
|
@ -40,13 +58,44 @@ class Travis::Api::App
|
|||
end
|
||||
|
||||
def repo
|
||||
@repo ||= Repository.by_slug(slug).first
|
||||
instance_variable_defined?(:@repo) ? @repo : @repo = Repository.by_slug(slug).first
|
||||
end
|
||||
|
||||
def slug
|
||||
repo = params[:repository] || {}
|
||||
repo.values_at(:owner_name, :name).join('/')
|
||||
end
|
||||
|
||||
def throttle
|
||||
@throttle ||= Throttle.new(slug)
|
||||
end
|
||||
|
||||
class Throttle < Struct.new(:slug)
|
||||
def throttled?
|
||||
current_requests >= max_requests
|
||||
end
|
||||
|
||||
def message
|
||||
'API throttled'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_requests
|
||||
@current_requests ||= begin
|
||||
sql = "repository_id = ? AND event_type = ? AND result = ? AND created_at > ?"
|
||||
Request.where(sql, repository.id, 'api', 'accepted', 1.hour.ago).count
|
||||
end
|
||||
end
|
||||
|
||||
def max_requests
|
||||
Travis.config.max_api_requests || 10
|
||||
end
|
||||
|
||||
def repository
|
||||
@repository ||= Repository.by_slug(slug).first || raise(Travis::RepositoryNotFoundError.new(slug: slug))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
115
lib/travis/api/attack.rb
Normal file
115
lib/travis/api/attack.rb
Normal file
|
@ -0,0 +1,115 @@
|
|||
require 'rack/attack'
|
||||
require 'netaddr'
|
||||
|
||||
class Rack::Attack
|
||||
class Request
|
||||
TOKEN = 'travis.access_token'.freeze
|
||||
|
||||
def travis_token
|
||||
env.fetch(TOKEN)
|
||||
end
|
||||
|
||||
def authenticated?
|
||||
env.include? TOKEN
|
||||
end
|
||||
|
||||
def identifier
|
||||
authenticated? ? travis_token.to_s : ip
|
||||
end
|
||||
end
|
||||
|
||||
def self.bantime(value)
|
||||
case Travis.env
|
||||
when "production" then value
|
||||
when "staging" then 10 # ban for 10 seconds on staging
|
||||
else 1
|
||||
end
|
||||
end
|
||||
|
||||
POST_SAFELIST = [
|
||||
"/auth/handshake",
|
||||
"/auth/post_message",
|
||||
"/auth/post_message/iframe"
|
||||
]
|
||||
|
||||
GITHUB_CIDR = NetAddr::CIDR.create('192.30.252.0/22')
|
||||
|
||||
safelist('safelist build status images') do |request|
|
||||
/\.(png|svg)$/.match(request.path)
|
||||
end
|
||||
|
||||
# https://help.github.com/articles/what-ip-addresses-does-github-use-that-i-should-safelist/
|
||||
safelist('safelist anything coming from github') do |request|
|
||||
request.ip && GITHUB_CIDR.contains?(request.ip)
|
||||
end
|
||||
|
||||
####
|
||||
# Whitelisted IP addresses
|
||||
safelist('safelist client requesting from redis') do |request|
|
||||
# TODO: deprecate :api_whitelisted_ips in favour of api_safelisted_ips
|
||||
Travis.redis.sismember(:api_whitelisted_ips, request.ip) || Travis.redis.sismember(:api_safelisted_ips, request.ip)
|
||||
end
|
||||
|
||||
####
|
||||
# Ban based on: IP address
|
||||
# Ban time: indefinite
|
||||
# Ban after: manually banned
|
||||
blocklist('block client requesting from redis') do |request|
|
||||
# TODO: deprecate :api_blacklisted_ips in favour of api_blocklisted_ips
|
||||
Travis.redis.sismember(:api_blacklisted_ips, request.ip) || Travis.redis.sismember(:api_blocklisted_ips, request.ip)
|
||||
end
|
||||
|
||||
####
|
||||
# Ban based on: IP address or access token
|
||||
# Ban time: 5 hours
|
||||
# Ban after: 10 POST requests within five minutes to /auth/github
|
||||
blocklist('hammering /auth/github') do |request|
|
||||
Rack::Attack::Allow2Ban.filter(request.identifier, maxretry: 2, findtime: 5.minutes, bantime: bantime(5.hours)) do
|
||||
request.post? and request.path == '/auth/github'
|
||||
end
|
||||
end
|
||||
|
||||
####
|
||||
# Ban based on: IP address or access token
|
||||
# Ban time: 1 hour
|
||||
# Ban after: 10 POST requests within 30 seconds
|
||||
blocklist('spamming with POST requests') do |request|
|
||||
Rack::Attack::Allow2Ban.filter(request.identifier, maxretry: 10, findtime: 30.seconds, bantime: bantime(1.hour)) do
|
||||
request.post? and not POST_SAFELIST.include? request.path
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
###
|
||||
# Throttle: unauthenticated requests to /auth/github - 1 per minute
|
||||
# Scoped by: IP address
|
||||
throttle('req/ip/1min', limit: 1, period: 1.minute) do |request|
|
||||
request.ip unless request.authenticated? and request.path == '/auth/github'
|
||||
end
|
||||
|
||||
###
|
||||
# Throttle: unauthenticated requests - 500 per minute
|
||||
# Scoped by: IP address
|
||||
throttle('req/ip/1min', limit: 500, period: 1.minute) do |request|
|
||||
request.ip unless request.authenticated?
|
||||
end
|
||||
|
||||
###
|
||||
# Throttle: authenticated requests - 2000 per minute
|
||||
# Scoped by: access token
|
||||
throttle('req/token/1min', limit: 2000, period: 1.minute) do |request|
|
||||
request.identifier
|
||||
end
|
||||
|
||||
if ENV["MEMCACHIER_SERVERS"]
|
||||
cache.store = Dalli::Client.new(
|
||||
ENV["MEMCACHIER_SERVERS"].split(","),
|
||||
username: ENV["MEMCACHIER_USERNAME"],
|
||||
password: ENV["MEMCACHIER_PASSWORD"],
|
||||
failover: true,
|
||||
socket_timeout: 1.5,
|
||||
socket_failure_delay: 0.2)
|
||||
else
|
||||
cache.store = ActiveSupport::Cache::MemoryStore.new
|
||||
end
|
||||
end
|
59
lib/travis/api/enqueue/services/cancel_model.rb
Normal file
59
lib/travis/api/enqueue/services/cancel_model.rb
Normal file
|
@ -0,0 +1,59 @@
|
|||
module Travis
|
||||
module Enqueue
|
||||
module Services
|
||||
|
||||
class CancelModel
|
||||
|
||||
attr_reader :current_user, :target
|
||||
|
||||
def initialize(current_user, params)
|
||||
@current_user = current_user
|
||||
@params = params
|
||||
target
|
||||
end
|
||||
|
||||
def messages
|
||||
messages = []
|
||||
messages << { :notice => "The #{type} was successfully cancelled." } if can_cancel?
|
||||
messages << { :error => "You are not authorized to cancel this #{type}." } unless authorized?
|
||||
messages << { :error => "The #{type} could not be cancelled." } unless build.cancelable?
|
||||
messages
|
||||
end
|
||||
|
||||
def push(event, payload)
|
||||
# target may have been retrieved with a :join query, so we need to reset the readonly status
|
||||
if can_cancel?
|
||||
::Sidekiq::Client.push(
|
||||
'queue' => 'hub',
|
||||
'class' => 'Travis::Hub::Sidekiq::Worker',
|
||||
#'args' => ["#{type}:cancel", @params]
|
||||
'args' => [event, payload]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def type
|
||||
@type ||= @params[:build_id] ? :build : :job
|
||||
end
|
||||
|
||||
def target
|
||||
if type == :build
|
||||
@target = Build.find(@params[:build_id])
|
||||
else
|
||||
@target = Job.find(@params[:job_id])
|
||||
end
|
||||
end
|
||||
|
||||
def can_cancel?
|
||||
authorized? && target.cancelable?
|
||||
end
|
||||
|
||||
# check on web
|
||||
def authorized?
|
||||
current_user.permission?(:pull, :repository_id => target.repository_id)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
64
lib/travis/api/enqueue/services/restart_model.rb
Normal file
64
lib/travis/api/enqueue/services/restart_model.rb
Normal file
|
@ -0,0 +1,64 @@
|
|||
module Travis
|
||||
module Enqueue
|
||||
module Services
|
||||
|
||||
class RestartModel
|
||||
attr_reader :current_user, :target
|
||||
|
||||
def initialize(current_user, params)
|
||||
@current_user = current_user
|
||||
@params = params
|
||||
target
|
||||
end
|
||||
|
||||
def push(event, payload)
|
||||
if current_user && target && accept?
|
||||
::Sidekiq::Client.push(
|
||||
'queue' => 'hub',
|
||||
'class' => 'Travis::Hub::Sidekiq::Worker',
|
||||
'args' => [event, payload]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def accept?
|
||||
current_user && permission? && resetable?
|
||||
end
|
||||
|
||||
def messages
|
||||
messages = []
|
||||
messages << { notice: "The #{type} was successfully restarted." } if accept?
|
||||
messages << { error: 'You do not seem to have sufficient permissions.' } unless permission?
|
||||
messages << { error: "This #{type} currently can not be restarted." } unless resetable?
|
||||
messages
|
||||
end
|
||||
|
||||
def type
|
||||
@type ||= @params[:build_id] ? :build : :job
|
||||
end
|
||||
|
||||
def target
|
||||
if type == :build
|
||||
@target = Build.find(@params[:build_id])
|
||||
else
|
||||
@target = Job.find(@params[:job_id])
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def permission?
|
||||
current_user.permission?(required_role, repository_id: target.repository_id)
|
||||
end
|
||||
|
||||
def resetable?
|
||||
target.resetable?
|
||||
end
|
||||
|
||||
def required_role
|
||||
Travis.config.roles.reset_model
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
68
lib/travis/api/serialize.rb
Normal file
68
lib/travis/api/serialize.rb
Normal file
|
@ -0,0 +1,68 @@
|
|||
require 'travis/api/serialize/formats'
|
||||
require 'travis/api/serialize/v0'
|
||||
require 'travis/api/serialize/v1'
|
||||
|
||||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
DEFAULT_VERSION = 'v2'
|
||||
|
||||
class << self
|
||||
def data(resource, options = {})
|
||||
new(resource, options).data
|
||||
end
|
||||
|
||||
def builder(resource, options = {})
|
||||
target = (options[:for] || 'http').to_s.camelize
|
||||
version = (options[:version] || default_version(options)).to_s.camelize
|
||||
type = (options[:type] || type_for(resource)).to_s.camelize.split('::')
|
||||
([version, target] + type).inject(self) do |const, name|
|
||||
begin
|
||||
if const && const.const_defined?(name.to_s.camelize, false)
|
||||
const.const_get(name, false)
|
||||
else
|
||||
nil
|
||||
end
|
||||
rescue NameError
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def new(resource, options = {})
|
||||
builder = builder(resource, options) || raise(ArgumentError, "cannot serialize #{resource.inspect}, options: #{options.inspect}")
|
||||
builder.new(resource, options[:params] || {})
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def type_for(resource)
|
||||
if arel_relation?(resource)
|
||||
type = resource.klass.name.pluralize
|
||||
else
|
||||
type = resource.class
|
||||
type = type.base_class if active_record?(type)
|
||||
type = type.name
|
||||
end
|
||||
type.split('::').last
|
||||
end
|
||||
|
||||
def arel_relation?(object)
|
||||
object.respond_to?(:klass)
|
||||
end
|
||||
|
||||
def active_record?(object)
|
||||
object.respond_to?(:base_class)
|
||||
end
|
||||
|
||||
def default_version(options)
|
||||
if options[:for].to_s.downcase == "pusher"
|
||||
"v0"
|
||||
else
|
||||
DEFAULT_VERSION
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
11
lib/travis/api/serialize/formats.rb
Normal file
11
lib/travis/api/serialize/formats.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module Formats
|
||||
def format_date(date)
|
||||
date && date.strftime('%Y-%m-%dT%H:%M:%SZ')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
25
lib/travis/api/serialize/serializer.rb
Normal file
25
lib/travis/api/serialize/serializer.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
require 'active_model_serializers'
|
||||
|
||||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
class ObjectSerializer < ActiveModel::Serializer
|
||||
def data
|
||||
as_json
|
||||
end
|
||||
end
|
||||
|
||||
class ArraySerializer < ActiveModel::ArraySerializer
|
||||
def data
|
||||
as_json
|
||||
end
|
||||
|
||||
def initialize(resource, options)
|
||||
options[:each_serializer] ||= V2::Http.const_get(options[:root].to_s.singularize.camelize)
|
||||
super(resource, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
6
lib/travis/api/serialize/v0.rb
Normal file
6
lib/travis/api/serialize/v0.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
# V0 is an internal api that we can change at any time
|
||||
|
||||
require 'travis/api/serialize/v0/event'
|
||||
require 'travis/api/serialize/v0/notification'
|
||||
require 'travis/api/serialize/v0/pusher'
|
||||
require 'travis/api/serialize/v0/worker'
|
2
lib/travis/api/serialize/v0/event.rb
Normal file
2
lib/travis/api/serialize/v0/event.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
require 'travis/api/serialize/v0/event/build'
|
||||
require 'travis/api/serialize/v0/event/job'
|
96
lib/travis/api/serialize/v0/event/build.rb
Normal file
96
lib/travis/api/serialize/v0/event/build.rb
Normal file
|
@ -0,0 +1,96 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V0
|
||||
module Event
|
||||
class Build
|
||||
include Formats
|
||||
|
||||
attr_reader :build, :repository, :request, :commit, :options
|
||||
|
||||
def initialize(build, options = {})
|
||||
@build = build
|
||||
@repository = build.repository
|
||||
@request = build.request
|
||||
@commit = build.commit
|
||||
# @options = options
|
||||
end
|
||||
|
||||
def data(extra = {})
|
||||
{
|
||||
'repository' => repository_data,
|
||||
'request' => request_data,
|
||||
'commit' => commit_data,
|
||||
'build' => build_data,
|
||||
'jobs' => build.matrix.map { |job| job_data(job) }
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def build_data
|
||||
{
|
||||
'id' => build.id,
|
||||
'repository_id' => build.repository_id,
|
||||
'commit_id' => build.commit_id,
|
||||
'number' => build.number,
|
||||
'pull_request' => build.pull_request?,
|
||||
'pull_request_number' => build.pull_request_number,
|
||||
'config' => build.config.try(:except, :source_key),
|
||||
'state' => build.state.to_s,
|
||||
'previous_state' => build.previous_state.to_s,
|
||||
'started_at' => format_date(build.started_at),
|
||||
'finished_at' => format_date(build.finished_at),
|
||||
'duration' => build.duration,
|
||||
'job_ids' => build.matrix_ids
|
||||
}
|
||||
end
|
||||
|
||||
def repository_data
|
||||
{
|
||||
'id' => repository.id,
|
||||
'key' => repository.key.try(:public_key),
|
||||
'slug' => repository.slug,
|
||||
'name' => repository.name,
|
||||
'owner_email' => repository.owner_email,
|
||||
'owner_avatar_url' => repository.owner.try(:avatar_url)
|
||||
}
|
||||
end
|
||||
|
||||
def request_data
|
||||
{
|
||||
'token' => request.token,
|
||||
'head_commit' => (request.head_commit || '')
|
||||
}
|
||||
end
|
||||
|
||||
def commit_data
|
||||
{
|
||||
'id' => commit.id,
|
||||
'sha' => commit.commit,
|
||||
'branch' => commit.branch,
|
||||
'message' => commit.message,
|
||||
'committed_at' => format_date(commit.committed_at),
|
||||
'author_name' => commit.author_name,
|
||||
'author_email' => commit.author_email,
|
||||
'committer_name' => commit.committer_name,
|
||||
'committer_email' => commit.committer_email,
|
||||
'compare_url' => commit.compare_url,
|
||||
}
|
||||
end
|
||||
|
||||
def job_data(job)
|
||||
{
|
||||
'id' => job.id,
|
||||
'number' => job.number,
|
||||
'state' => job.state.to_s,
|
||||
'tags' => job.tags
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
37
lib/travis/api/serialize/v0/event/job.rb
Normal file
37
lib/travis/api/serialize/v0/event/job.rb
Normal file
|
@ -0,0 +1,37 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V0
|
||||
module Event
|
||||
class Job
|
||||
include Formats
|
||||
|
||||
attr_reader :job
|
||||
|
||||
def initialize(job, options = {})
|
||||
@job = job
|
||||
# @options = options
|
||||
end
|
||||
|
||||
def data(extra = {})
|
||||
{
|
||||
'job' => job_data,
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def job_data
|
||||
{
|
||||
'queue' => job.queue,
|
||||
'created_at' => job.created_at,
|
||||
'started_at' => job.started_at,
|
||||
'finished_at' => job.finished_at,
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
3
lib/travis/api/serialize/v0/notification.rb
Normal file
3
lib/travis/api/serialize/v0/notification.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
require 'travis/api/serialize/v0/notification/build'
|
||||
require 'travis/api/serialize/v0/notification/repository'
|
||||
require 'travis/api/serialize/v0/notification/user'
|
29
lib/travis/api/serialize/v0/notification/build.rb
Normal file
29
lib/travis/api/serialize/v0/notification/build.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V0
|
||||
module Notification
|
||||
class Build
|
||||
attr_reader :build
|
||||
|
||||
def initialize(build, options = {})
|
||||
@build = build
|
||||
end
|
||||
|
||||
def data
|
||||
{
|
||||
'build' => build_data
|
||||
}
|
||||
end
|
||||
|
||||
def build_data
|
||||
{
|
||||
'id' => build.id
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
30
lib/travis/api/serialize/v0/notification/repository.rb
Normal file
30
lib/travis/api/serialize/v0/notification/repository.rb
Normal file
|
@ -0,0 +1,30 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V0
|
||||
module Notification
|
||||
class Repository
|
||||
attr_reader :repository
|
||||
|
||||
def initialize(repository, options = {})
|
||||
@repository = repository
|
||||
end
|
||||
|
||||
def data
|
||||
{
|
||||
'repository' => repository_data
|
||||
}
|
||||
end
|
||||
|
||||
def repository_data
|
||||
{
|
||||
'id' => repository.id,
|
||||
'slug' => repository.slug
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
30
lib/travis/api/serialize/v0/notification/user.rb
Normal file
30
lib/travis/api/serialize/v0/notification/user.rb
Normal file
|
@ -0,0 +1,30 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V0
|
||||
module Notification
|
||||
class User
|
||||
attr_reader :user
|
||||
|
||||
def initialize(user, options = {})
|
||||
@user = user
|
||||
end
|
||||
|
||||
def data
|
||||
{
|
||||
'user' => user_data
|
||||
}
|
||||
end
|
||||
|
||||
def user_data
|
||||
{
|
||||
'id' => user.id,
|
||||
'login' => user.login
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
3
lib/travis/api/serialize/v0/pusher.rb
Normal file
3
lib/travis/api/serialize/v0/pusher.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
require 'travis/api/serialize/v0/pusher/annotation'
|
||||
require 'travis/api/serialize/v0/pusher/build'
|
||||
require 'travis/api/serialize/v0/pusher/job'
|
35
lib/travis/api/serialize/v0/pusher/annotation.rb
Normal file
35
lib/travis/api/serialize/v0/pusher/annotation.rb
Normal file
|
@ -0,0 +1,35 @@
|
|||
require 'travis/api/serialize/v0/pusher/annotation/created'
|
||||
require 'travis/api/serialize/v0/pusher/annotation/updated'
|
||||
|
||||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V0
|
||||
module Pusher
|
||||
class Annotation
|
||||
include Formats
|
||||
|
||||
attr_reader :annotation
|
||||
|
||||
def initialize(annotation, options = {})
|
||||
@annotation = annotation
|
||||
end
|
||||
|
||||
def data
|
||||
{
|
||||
"annotation" => {
|
||||
"id" => annotation.id,
|
||||
"job_id" => annotation.job_id,
|
||||
"description" => annotation.description,
|
||||
"url" => annotation.url,
|
||||
"status" => annotation.status,
|
||||
"provider_name" => annotation.annotation_provider.name,
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
14
lib/travis/api/serialize/v0/pusher/annotation/created.rb
Normal file
14
lib/travis/api/serialize/v0/pusher/annotation/created.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V0
|
||||
module Pusher
|
||||
class Annotation
|
||||
class Created < Annotation
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
14
lib/travis/api/serialize/v0/pusher/annotation/updated.rb
Normal file
14
lib/travis/api/serialize/v0/pusher/annotation/updated.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V0
|
||||
module Pusher
|
||||
class Annotation
|
||||
class Updated < Annotation
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
112
lib/travis/api/serialize/v0/pusher/build.rb
Normal file
112
lib/travis/api/serialize/v0/pusher/build.rb
Normal file
|
@ -0,0 +1,112 @@
|
|||
require 'travis/api/serialize/v0/pusher/build/canceled'
|
||||
require 'travis/api/serialize/v0/pusher/build/created'
|
||||
require 'travis/api/serialize/v0/pusher/build/received'
|
||||
require 'travis/api/serialize/v0/pusher/build/started'
|
||||
require 'travis/api/serialize/v0/pusher/build/finished'
|
||||
|
||||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V0
|
||||
module Pusher
|
||||
class Build
|
||||
include Formats
|
||||
|
||||
attr_reader :build, :options
|
||||
|
||||
def initialize(build, options = {})
|
||||
@build = build
|
||||
@options = options
|
||||
end
|
||||
|
||||
def data
|
||||
{
|
||||
'build' => build_data(build),
|
||||
'commit' => commit_data(build.commit),
|
||||
'repository' => repository_data(build.repository)
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def build_data(build)
|
||||
commit = build.commit
|
||||
{
|
||||
'id' => build.id,
|
||||
'repository_id' => build.repository_id,
|
||||
'commit_id' => build.commit_id,
|
||||
'number' => build.number,
|
||||
'pull_request' => build.pull_request?,
|
||||
'pull_request_title' => build.pull_request_title,
|
||||
'pull_request_number' => build.pull_request_number,
|
||||
'state' => build.state.to_s,
|
||||
'started_at' => format_date(build.started_at),
|
||||
'finished_at' => format_date(build.finished_at),
|
||||
'duration' => build.duration,
|
||||
'job_ids' => build.matrix_ids,
|
||||
'event_type' => build.event_type,
|
||||
|
||||
# this is a legacy thing, we should think about removing it
|
||||
'commit' => commit.commit,
|
||||
'branch' => commit.branch,
|
||||
'message' => commit.message,
|
||||
'compare_url' => commit.compare_url,
|
||||
'committed_at' => format_date(commit.committed_at),
|
||||
'author_name' => commit.author_name,
|
||||
'author_email' => commit.author_email,
|
||||
'committer_name' => commit.committer_name,
|
||||
'committer_email' => commit.committer_email
|
||||
}
|
||||
end
|
||||
|
||||
def commit_data(commit)
|
||||
{
|
||||
'id' => commit.id,
|
||||
'sha' => commit.commit,
|
||||
'branch' => commit.branch,
|
||||
'message' => commit.message,
|
||||
'committed_at' => format_date(commit.committed_at),
|
||||
'author_name' => commit.author_name,
|
||||
'author_email' => commit.author_email,
|
||||
'committer_name' => commit.committer_name,
|
||||
'committer_email' => commit.committer_email,
|
||||
'compare_url' => commit.compare_url,
|
||||
}
|
||||
end
|
||||
|
||||
def repository_data(repository)
|
||||
{
|
||||
'id' => repository.id,
|
||||
'slug' => repository.slug,
|
||||
'description' => repository.description,
|
||||
'private' => repository.private,
|
||||
'last_build_id' => repository.last_build_id,
|
||||
'last_build_number' => repository.last_build_number,
|
||||
'last_build_state' => repository.last_build_state.to_s,
|
||||
'last_build_duration' => repository.last_build_duration,
|
||||
'last_build_language' => nil,
|
||||
'last_build_started_at' => format_date(repository.last_build_started_at),
|
||||
'last_build_finished_at' => format_date(repository.last_build_finished_at),
|
||||
'github_language' => repository.github_language,
|
||||
'default_branch' => {
|
||||
'name' => repository.default_branch,
|
||||
'last_build_id' => last_build_on_default_branch_id(repository)
|
||||
},
|
||||
'active' => repository.active,
|
||||
'current_build_id' => repository.current_build_id
|
||||
}
|
||||
end
|
||||
|
||||
def last_build_on_default_branch_id(repository)
|
||||
default_branch = Branch.where(repository_id: repository.id, name: repository.default_branch).first
|
||||
|
||||
if default_branch
|
||||
default_branch.last_build_id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
14
lib/travis/api/serialize/v0/pusher/build/canceled.rb
Normal file
14
lib/travis/api/serialize/v0/pusher/build/canceled.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V0
|
||||
module Pusher
|
||||
class Build
|
||||
class Canceled < Build
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
14
lib/travis/api/serialize/v0/pusher/build/created.rb
Normal file
14
lib/travis/api/serialize/v0/pusher/build/created.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V0
|
||||
module Pusher
|
||||
class Build
|
||||
class Created < Build
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
14
lib/travis/api/serialize/v0/pusher/build/finished.rb
Normal file
14
lib/travis/api/serialize/v0/pusher/build/finished.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V0
|
||||
module Pusher
|
||||
class Build
|
||||
class Finished < Build
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
14
lib/travis/api/serialize/v0/pusher/build/received.rb
Normal file
14
lib/travis/api/serialize/v0/pusher/build/received.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V0
|
||||
module Pusher
|
||||
class Build
|
||||
class Received < Build
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
49
lib/travis/api/serialize/v0/pusher/build/received/job.rb
Normal file
49
lib/travis/api/serialize/v0/pusher/build/received/job.rb
Normal file
|
@ -0,0 +1,49 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V0
|
||||
module Pusher
|
||||
class Build
|
||||
class Received < Build
|
||||
class Job
|
||||
include Formats, V1::Helpers::Legacy
|
||||
|
||||
attr_reader :job, :commit
|
||||
|
||||
def initialize(job)
|
||||
@job = job
|
||||
@commit = job.commit
|
||||
end
|
||||
|
||||
def data
|
||||
{
|
||||
'id' => job.id,
|
||||
'repository_id' => job.repository_id,
|
||||
'repository_private' => repository.private,
|
||||
'parent_id' => job.source_id,
|
||||
'number' => job.number,
|
||||
'state' => job.state.to_s,
|
||||
'result' => legacy_job_result(job),
|
||||
'config' => job.obfuscated_config,
|
||||
'commit' => commit.commit,
|
||||
'branch' => commit.branch,
|
||||
'message' => commit.message,
|
||||
'compare_url' => commit.compare_url,
|
||||
'started_at' => format_date(job.started_at),
|
||||
'finished_at' => format_date(job.finished_at),
|
||||
'committed_at' => format_date(commit.committed_at),
|
||||
'author_name' => commit.author_name,
|
||||
'author_email' => commit.author_email,
|
||||
'committer_name' => commit.committer_name,
|
||||
'committer_email' => commit.committer_email,
|
||||
'allow_failure' => job.allow_failure
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
14
lib/travis/api/serialize/v0/pusher/build/started.rb
Normal file
14
lib/travis/api/serialize/v0/pusher/build/started.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V0
|
||||
module Pusher
|
||||
class Build
|
||||
class Started < Build
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
49
lib/travis/api/serialize/v0/pusher/build/started/job.rb
Normal file
49
lib/travis/api/serialize/v0/pusher/build/started/job.rb
Normal file
|
@ -0,0 +1,49 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V0
|
||||
module Pusher
|
||||
class Build
|
||||
class Started < Build
|
||||
class Job
|
||||
include Formats, V1::Helpers::Legacy
|
||||
|
||||
attr_reader :job, :commit
|
||||
|
||||
def initialize(job)
|
||||
@job = job
|
||||
@commit = job.commit
|
||||
end
|
||||
|
||||
def data
|
||||
{
|
||||
'id' => job.id,
|
||||
'repository_id' => job.repository_id,
|
||||
'repository_private' => repository.private,
|
||||
'parent_id' => job.source_id,
|
||||
'number' => job.number,
|
||||
'state' => job.state.to_s,
|
||||
'result' => legacy_job_result(job),
|
||||
'config' => job.obfuscated_config,
|
||||
'commit' => commit.commit,
|
||||
'branch' => commit.branch,
|
||||
'message' => commit.message,
|
||||
'compare_url' => commit.compare_url,
|
||||
'started_at' => format_date(job.started_at),
|
||||
'finished_at' => format_date(job.finished_at),
|
||||
'committed_at' => format_date(commit.committed_at),
|
||||
'author_name' => commit.author_name,
|
||||
'author_email' => commit.author_email,
|
||||
'committer_name' => commit.committer_name,
|
||||
'committer_email' => commit.committer_email,
|
||||
'allow_failure' => job.allow_failure
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
69
lib/travis/api/serialize/v0/pusher/job.rb
Normal file
69
lib/travis/api/serialize/v0/pusher/job.rb
Normal file
|
@ -0,0 +1,69 @@
|
|||
require 'travis/api/serialize/v0/pusher/job/canceled'
|
||||
require 'travis/api/serialize/v0/pusher/job/created'
|
||||
require 'travis/api/serialize/v0/pusher/job/log'
|
||||
require 'travis/api/serialize/v0/pusher/job/received'
|
||||
require 'travis/api/serialize/v0/pusher/job/started'
|
||||
require 'travis/api/serialize/v0/pusher/job/finished'
|
||||
|
||||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V0
|
||||
module Pusher
|
||||
class Job
|
||||
include Formats
|
||||
|
||||
attr_reader :job, :options
|
||||
|
||||
def initialize(job, options = {})
|
||||
@job = job
|
||||
@options = options
|
||||
end
|
||||
|
||||
def data
|
||||
job_data(job).merge(
|
||||
'commit' => commit_data(job.commit)
|
||||
)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def job_data(job)
|
||||
{
|
||||
'id' => job.id,
|
||||
'repository_id' => job.repository_id,
|
||||
'repository_slug' => job.repository.slug,
|
||||
'repository_private' => job.repository.private,
|
||||
'build_id' => job.source_id,
|
||||
'commit_id' => job.commit_id,
|
||||
'log_id' => job.log_id,
|
||||
'number' => job.number,
|
||||
'state' => job.state.to_s,
|
||||
'started_at' => format_date(job.started_at),
|
||||
'finished_at' => format_date(job.finished_at),
|
||||
'queue' => job.queue,
|
||||
'allow_failure' => job.allow_failure,
|
||||
'annotation_ids' => job.annotation_ids
|
||||
}
|
||||
end
|
||||
|
||||
def commit_data(commit)
|
||||
{
|
||||
'id' => commit.id,
|
||||
'sha' => commit.commit,
|
||||
'branch' => commit.branch,
|
||||
'message' => commit.message,
|
||||
'committed_at' => format_date(commit.committed_at),
|
||||
'author_name' => commit.author_name,
|
||||
'author_email' => commit.author_email,
|
||||
'committer_name' => commit.committer_name,
|
||||
'committer_email' => commit.committer_email,
|
||||
'compare_url' => commit.compare_url,
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
14
lib/travis/api/serialize/v0/pusher/job/canceled.rb
Normal file
14
lib/travis/api/serialize/v0/pusher/job/canceled.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V0
|
||||
module Pusher
|
||||
class Job
|
||||
class Canceled < Job
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
14
lib/travis/api/serialize/v0/pusher/job/created.rb
Normal file
14
lib/travis/api/serialize/v0/pusher/job/created.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V0
|
||||
module Pusher
|
||||
class Job
|
||||
class Created < Job
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
14
lib/travis/api/serialize/v0/pusher/job/finished.rb
Normal file
14
lib/travis/api/serialize/v0/pusher/job/finished.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V0
|
||||
module Pusher
|
||||
class Job
|
||||
class Finished < Job
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
32
lib/travis/api/serialize/v0/pusher/job/log.rb
Normal file
32
lib/travis/api/serialize/v0/pusher/job/log.rb
Normal file
|
@ -0,0 +1,32 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V0
|
||||
module Pusher
|
||||
class Job
|
||||
class Log
|
||||
attr_reader :job, :options
|
||||
|
||||
def initialize(job, options = {})
|
||||
@job = job
|
||||
@options = options
|
||||
end
|
||||
|
||||
def data
|
||||
{
|
||||
'id' => job.id,
|
||||
'build_id' => job.source_id,
|
||||
'repository_id' => job.repository_id,
|
||||
'repository_private' => repository.private,
|
||||
'_log' => options[:_log],
|
||||
'number' => options[:number],
|
||||
'final' => options[:final]
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
14
lib/travis/api/serialize/v0/pusher/job/received.rb
Normal file
14
lib/travis/api/serialize/v0/pusher/job/received.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V0
|
||||
module Pusher
|
||||
class Job
|
||||
class Received < Job
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
14
lib/travis/api/serialize/v0/pusher/job/started.rb
Normal file
14
lib/travis/api/serialize/v0/pusher/job/started.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V0
|
||||
module Pusher
|
||||
class Job
|
||||
class Started < Job
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
1
lib/travis/api/serialize/v0/worker.rb
Normal file
1
lib/travis/api/serialize/v0/worker.rb
Normal file
|
@ -0,0 +1 @@
|
|||
require 'travis/api/serialize/v0/worker/job'
|
35
lib/travis/api/serialize/v0/worker/job.rb
Normal file
35
lib/travis/api/serialize/v0/worker/job.rb
Normal file
|
@ -0,0 +1,35 @@
|
|||
require 'travis/api/serialize/v0/worker/job/test'
|
||||
|
||||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V0
|
||||
module Worker
|
||||
class Job
|
||||
attr_reader :job
|
||||
|
||||
def initialize(job, options = {})
|
||||
@job = job
|
||||
end
|
||||
|
||||
def commit
|
||||
job.commit
|
||||
end
|
||||
|
||||
def repository
|
||||
job.repository
|
||||
end
|
||||
|
||||
def request
|
||||
build.request
|
||||
end
|
||||
|
||||
def build
|
||||
job.source
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
120
lib/travis/api/serialize/v0/worker/job/test.rb
Normal file
120
lib/travis/api/serialize/v0/worker/job/test.rb
Normal file
|
@ -0,0 +1,120 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V0
|
||||
module Worker
|
||||
class Job
|
||||
class Test < Job
|
||||
include Formats
|
||||
|
||||
def data
|
||||
{
|
||||
'type' => 'test',
|
||||
# TODO legacy. remove this once workers respond to a 'job' key
|
||||
'build' => job_data,
|
||||
'job' => job_data,
|
||||
'source' => build_data,
|
||||
'repository' => repository_data,
|
||||
'pull_request' => commit.pull_request? ? pull_request_data : false,
|
||||
'config' => job.decrypted_config,
|
||||
'queue' => job.queue,
|
||||
'uuid' => Travis.uuid,
|
||||
'ssh_key' => ssh_key,
|
||||
'env_vars' => env_vars,
|
||||
'timeouts' => timeouts
|
||||
}
|
||||
end
|
||||
|
||||
def build_data
|
||||
{
|
||||
'id' => build.id,
|
||||
'number' => build.number
|
||||
}
|
||||
end
|
||||
|
||||
def job_data
|
||||
data = {
|
||||
'id' => job.id,
|
||||
'number' => job.number,
|
||||
'commit' => commit.commit,
|
||||
'commit_range' => commit.range,
|
||||
'commit_message' => commit.message,
|
||||
'branch' => commit.branch,
|
||||
'ref' => commit.pull_request? ? commit.ref : nil,
|
||||
'state' => job.state.to_s,
|
||||
'secure_env_enabled' => job.secure_env_enabled?
|
||||
}
|
||||
data['tag'] = request.tag_name if include_tag_name?
|
||||
data['pull_request'] = commit.pull_request? ? commit.pull_request_number : false
|
||||
data
|
||||
end
|
||||
|
||||
def repository_data
|
||||
{
|
||||
'id' => repository.id,
|
||||
'slug' => repository.slug,
|
||||
'github_id' => repository.github_id,
|
||||
'source_url' => repository.source_url,
|
||||
'api_url' => repository.api_url,
|
||||
'last_build_id' => repository.last_build_id,
|
||||
'last_build_number' => repository.last_build_number,
|
||||
'last_build_started_at' => format_date(repository.last_build_started_at),
|
||||
'last_build_finished_at' => format_date(repository.last_build_finished_at),
|
||||
'last_build_duration' => repository.last_build_duration,
|
||||
'last_build_state' => repository.last_build_state.to_s,
|
||||
'description' => repository.description,
|
||||
'default_branch' => repository.default_branch
|
||||
}
|
||||
end
|
||||
|
||||
def pull_request_data
|
||||
{
|
||||
'number' => commit.pull_request_number,
|
||||
'head_repo' => request.head_repo,
|
||||
'base_repo' => request.base_repo,
|
||||
'head_branch' => request.head_branch,
|
||||
'base_branch' => request.base_branch
|
||||
}
|
||||
end
|
||||
|
||||
def ssh_key
|
||||
nil
|
||||
end
|
||||
|
||||
def env_vars
|
||||
vars = settings.env_vars
|
||||
vars = vars.public unless job.secure_env_enabled?
|
||||
|
||||
vars.map do |var|
|
||||
{
|
||||
'name' => var.name,
|
||||
'value' => var.value.decrypt,
|
||||
'public' => var.public
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def timeouts
|
||||
{ 'hard_limit' => timeout(:hard_limit), 'log_silence' => timeout(:log_silence) }
|
||||
end
|
||||
|
||||
def timeout(type)
|
||||
timeout = settings.send(:"timeout_#{type}")
|
||||
timeout = timeout * 60 if timeout # worker handles timeouts in seconds
|
||||
timeout
|
||||
end
|
||||
|
||||
def include_tag_name?
|
||||
Travis.config.include_tag_name_in_worker_payload && request.tag_name.present?
|
||||
end
|
||||
|
||||
def settings
|
||||
repository.settings
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
4
lib/travis/api/serialize/v1.rb
Normal file
4
lib/travis/api/serialize/v1.rb
Normal file
|
@ -0,0 +1,4 @@
|
|||
require 'travis/api/serialize/v1/archive'
|
||||
require 'travis/api/serialize/v1/http'
|
||||
require 'travis/api/serialize/v1/helpers'
|
||||
require 'travis/api/serialize/v1/webhook'
|
1
lib/travis/api/serialize/v1/archive.rb
Normal file
1
lib/travis/api/serialize/v1/archive.rb
Normal file
|
@ -0,0 +1 @@
|
|||
require 'travis/api/serialize/v1/archive/build'
|
52
lib/travis/api/serialize/v1/archive/build.rb
Normal file
52
lib/travis/api/serialize/v1/archive/build.rb
Normal file
|
@ -0,0 +1,52 @@
|
|||
require 'travis/api/serialize/v1/archive/build/job'
|
||||
|
||||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V1
|
||||
module Archive
|
||||
class Build
|
||||
include Formats
|
||||
|
||||
attr_reader :build, :commit, :repository
|
||||
|
||||
def initialize(build, options = {})
|
||||
@build = build
|
||||
@commit = build.commit
|
||||
@repository = build.repository
|
||||
end
|
||||
|
||||
def data
|
||||
{
|
||||
'id' => build.id,
|
||||
'number' => build.number,
|
||||
'config' => build.obfuscated_config.stringify_keys,
|
||||
'result' => 0,
|
||||
'started_at' => format_date(build.started_at),
|
||||
'finished_at' => format_date(build.finished_at),
|
||||
'duration' => build.duration,
|
||||
'commit' => commit.commit,
|
||||
'branch' => commit.branch,
|
||||
'message' => commit.message,
|
||||
'committed_at' => format_date(commit.committed_at),
|
||||
'author_name' => commit.author_name,
|
||||
'author_email' => commit.author_email,
|
||||
'committer_name' => commit.committer_name,
|
||||
'committer_email' => commit.committer_email,
|
||||
'matrix' => build.matrix.map { |job| Job.new(job).data },
|
||||
'repository' => repository_data
|
||||
}
|
||||
end
|
||||
|
||||
def repository_data
|
||||
{
|
||||
'id' => repository.id,
|
||||
'slug' => repository.slug
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
33
lib/travis/api/serialize/v1/archive/build/job.rb
Normal file
33
lib/travis/api/serialize/v1/archive/build/job.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V1
|
||||
module Archive
|
||||
class Build
|
||||
class Job
|
||||
include Formats
|
||||
|
||||
attr_reader :job, :commit
|
||||
|
||||
def initialize(job)
|
||||
@job = job
|
||||
@commit = job.commit
|
||||
end
|
||||
|
||||
def data
|
||||
{
|
||||
'id' => job.id,
|
||||
'number' => job.number,
|
||||
'config' => job.obfuscated_config,
|
||||
'started_at' => format_date(job.started_at),
|
||||
'finished_at' => format_date(job.finished_at),
|
||||
'log' => job.log_content
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
1
lib/travis/api/serialize/v1/helpers.rb
Normal file
1
lib/travis/api/serialize/v1/helpers.rb
Normal file
|
@ -0,0 +1 @@
|
|||
require 'travis/api/serialize/v1/helpers/legacy'
|
36
lib/travis/api/serialize/v1/helpers/legacy.rb
Normal file
36
lib/travis/api/serialize/v1/helpers/legacy.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V1
|
||||
module Helpers
|
||||
module Legacy
|
||||
RESULTS = {
|
||||
passed: 0,
|
||||
failed: 1
|
||||
}
|
||||
|
||||
def legacy_repository_last_build_result(repository)
|
||||
RESULTS[repository.last_build_state.try(:to_sym)]
|
||||
end
|
||||
|
||||
def legacy_build_state(build)
|
||||
build.finished? ? 'finished' : build.state.to_s
|
||||
end
|
||||
|
||||
def legacy_build_result(build)
|
||||
RESULTS[build.state.try(:to_sym)]
|
||||
end
|
||||
|
||||
def legacy_job_state(job)
|
||||
job.finished? ? 'finished' : job.state.to_s
|
||||
end
|
||||
|
||||
def legacy_job_result(job)
|
||||
RESULTS[job.state.try(:to_sym)]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
9
lib/travis/api/serialize/v1/http.rb
Normal file
9
lib/travis/api/serialize/v1/http.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
require 'travis/api/serialize/v1/http/branches'
|
||||
require 'travis/api/serialize/v1/http/build'
|
||||
require 'travis/api/serialize/v1/http/builds'
|
||||
require 'travis/api/serialize/v1/http/hooks'
|
||||
require 'travis/api/serialize/v1/http/job'
|
||||
require 'travis/api/serialize/v1/http/jobs'
|
||||
require 'travis/api/serialize/v1/http/repositories'
|
||||
require 'travis/api/serialize/v1/http/repository'
|
||||
require 'travis/api/serialize/v1/http/user'
|
45
lib/travis/api/serialize/v1/http/branches.rb
Normal file
45
lib/travis/api/serialize/v1/http/branches.rb
Normal file
|
@ -0,0 +1,45 @@
|
|||
require 'travis/api/serialize/v1/helpers/legacy'
|
||||
|
||||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V1
|
||||
module Http
|
||||
class Branches
|
||||
include Formats, Helpers::Legacy
|
||||
|
||||
attr_reader :builds, :options
|
||||
|
||||
def initialize(builds, options = {})
|
||||
builds = builds.last_finished_builds_by_branches if builds.is_a?(Repository) # TODO remove, bc
|
||||
@builds = builds
|
||||
end
|
||||
|
||||
def cache_key
|
||||
"branches-#{builds.map(&:id).join('-')}"
|
||||
end
|
||||
|
||||
def updated_at
|
||||
builds.compact.map(&:finished_at).compact.sort.first
|
||||
end
|
||||
|
||||
def data
|
||||
builds.compact.map do |build|
|
||||
{
|
||||
'repository_id' => build.repository_id,
|
||||
'build_id' => build.id,
|
||||
'commit' => build.commit.commit,
|
||||
'branch' => build.commit.branch,
|
||||
'message' => build.commit.message,
|
||||
'result' => legacy_build_result(build),
|
||||
'finished_at' => format_date(build.finished_at),
|
||||
'started_at' => format_date(build.started_at)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
49
lib/travis/api/serialize/v1/http/build.rb
Normal file
49
lib/travis/api/serialize/v1/http/build.rb
Normal file
|
@ -0,0 +1,49 @@
|
|||
require 'travis/api/serialize/v1/http/build/job'
|
||||
|
||||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V1
|
||||
module Http
|
||||
class Build
|
||||
include Formats, Helpers::Legacy
|
||||
|
||||
attr_reader :build, :commit, :request
|
||||
|
||||
def initialize(build, options = {})
|
||||
@build = build
|
||||
@commit = build.commit
|
||||
@request = build.request
|
||||
end
|
||||
|
||||
def data
|
||||
{
|
||||
'id' => build.id,
|
||||
'repository_id' => build.repository_id,
|
||||
'number' => build.number,
|
||||
'config' => build.obfuscated_config.stringify_keys,
|
||||
'state' => legacy_build_state(build),
|
||||
'result' => legacy_build_result(build),
|
||||
'status' => legacy_build_result(build),
|
||||
'started_at' => format_date(build.started_at),
|
||||
'finished_at' => format_date(build.finished_at),
|
||||
'duration' => build.duration,
|
||||
'commit' => commit.commit,
|
||||
'branch' => commit.branch,
|
||||
'message' => commit.message,
|
||||
'committed_at' => format_date(commit.committed_at),
|
||||
'author_name' => commit.author_name,
|
||||
'author_email' => commit.author_email,
|
||||
'committer_name' => commit.committer_name,
|
||||
'committer_email' => commit.committer_email,
|
||||
'compare_url' => commit.compare_url,
|
||||
'event_type' => build.event_type,
|
||||
'matrix' => build.matrix.map { |job| Job.new(job).data },
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
34
lib/travis/api/serialize/v1/http/build/job.rb
Normal file
34
lib/travis/api/serialize/v1/http/build/job.rb
Normal file
|
@ -0,0 +1,34 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V1
|
||||
module Http
|
||||
class Build
|
||||
class Job
|
||||
include Formats, Helpers::Legacy
|
||||
|
||||
attr_reader :job
|
||||
|
||||
def initialize(job)
|
||||
@job = job
|
||||
end
|
||||
|
||||
def data
|
||||
{
|
||||
'id' => job.id,
|
||||
'repository_id' => job.repository_id,
|
||||
'number' => job.number,
|
||||
'config' => job.obfuscated_config.stringify_keys,
|
||||
'result' => legacy_job_result(job),
|
||||
'started_at' => format_date(job.started_at),
|
||||
'finished_at' => format_date(job.finished_at),
|
||||
'allow_failure' => job.allow_failure
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
40
lib/travis/api/serialize/v1/http/builds.rb
Normal file
40
lib/travis/api/serialize/v1/http/builds.rb
Normal file
|
@ -0,0 +1,40 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V1
|
||||
module Http
|
||||
class Builds
|
||||
include Formats, Helpers::Legacy
|
||||
|
||||
attr_reader :builds
|
||||
|
||||
def initialize(builds, options = {})
|
||||
@builds = builds
|
||||
end
|
||||
|
||||
def data
|
||||
builds.map { |build| build_data(build) }
|
||||
end
|
||||
|
||||
def build_data(build)
|
||||
{
|
||||
'id' => build.id,
|
||||
'repository_id' => build.repository_id,
|
||||
'number' => build.number,
|
||||
'state' => legacy_build_state(build),
|
||||
'result' => legacy_build_result(build),
|
||||
'started_at' => format_date(build.started_at),
|
||||
'finished_at' => format_date(build.finished_at),
|
||||
'duration' => build.duration,
|
||||
'commit' => build.commit.commit,
|
||||
'branch' => build.commit.branch,
|
||||
'message' => build.commit.message,
|
||||
'event_type' => build.event_type,
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
36
lib/travis/api/serialize/v1/http/hooks.rb
Normal file
36
lib/travis/api/serialize/v1/http/hooks.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V1
|
||||
module Http
|
||||
class Hooks
|
||||
attr_reader :repos, :options
|
||||
|
||||
def initialize(repos, options = {})
|
||||
@repos = repos
|
||||
@options = options
|
||||
end
|
||||
|
||||
def data
|
||||
repos.map { |repo| repo_data(repo) }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def repo_data(repo)
|
||||
{
|
||||
'uid' => [repo.owner_name, repo.name].join(':'),
|
||||
'url' => "https://github.com/#{repo.owner_name}/#{repo.name}",
|
||||
'name' => repo.name,
|
||||
'owner_name' => repo.owner_name,
|
||||
'description' => repo.description,
|
||||
'active' => repo.active,
|
||||
'private' => repo.private
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,49 +1,32 @@
|
|||
module Travis
|
||||
module Api
|
||||
module V2
|
||||
module Http
|
||||
class Jobs
|
||||
include Formats
|
||||
module Serialize
|
||||
module V1
|
||||
module Http
|
||||
class Job
|
||||
include Formats, Helpers::Legacy
|
||||
|
||||
attr_reader :jobs, :options
|
||||
attr_reader :job, :commit
|
||||
|
||||
def initialize(jobs, options = {})
|
||||
@jobs = jobs
|
||||
@options = options
|
||||
end
|
||||
|
||||
def data
|
||||
{
|
||||
'jobs' => jobs.map { |job| job_data(job) },
|
||||
'commits' => jobs.map { |job| commit_data(job.commit) }
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def job_data(job)
|
||||
{
|
||||
'id' => job.id,
|
||||
'repository_id' => job.repository_id,
|
||||
'repository_slug' => job.repository.slug,
|
||||
'build_id' => job.source_id,
|
||||
'commit_id' => job.commit_id,
|
||||
'log_id' => job.log_id,
|
||||
'number' => job.number,
|
||||
'config' => job.obfuscated_config.stringify_keys,
|
||||
'state' => job.state.to_s,
|
||||
'started_at' => format_date(job.started_at),
|
||||
'finished_at' => format_date(job.finished_at),
|
||||
'queue' => job.queue,
|
||||
'allow_failure' => job.allow_failure,
|
||||
'tags' => job.tags
|
||||
}
|
||||
def initialize(job, options = {})
|
||||
@job = job
|
||||
@commit = job.commit
|
||||
end
|
||||
|
||||
def commit_data(commit)
|
||||
def data
|
||||
{
|
||||
'id' => commit.id,
|
||||
'sha' => commit.commit,
|
||||
'id' => job.id,
|
||||
'number' => job.number,
|
||||
'config' => job.obfuscated_config.stringify_keys,
|
||||
'repository_id' => job.repository_id,
|
||||
'build_id' => job.source_id,
|
||||
'state' => job.finished? ? 'finished' : job.state.to_s,
|
||||
'result' => legacy_job_result(job),
|
||||
'status' => legacy_job_result(job),
|
||||
'started_at' => format_date(job.started_at),
|
||||
'finished_at' => format_date(job.finished_at),
|
||||
'log' => job.log_content,
|
||||
'commit' => commit.commit,
|
||||
'branch' => commit.branch,
|
||||
'message' => commit.message,
|
||||
'committed_at' => format_date(commit.committed_at),
|
||||
|
@ -52,8 +35,10 @@ module Travis
|
|||
'committer_name' => commit.committer_name,
|
||||
'committer_email' => commit.committer_email,
|
||||
'compare_url' => commit.compare_url,
|
||||
'worker' => job.worker
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
36
lib/travis/api/serialize/v1/http/jobs.rb
Normal file
36
lib/travis/api/serialize/v1/http/jobs.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V1
|
||||
module Http
|
||||
class Jobs
|
||||
include Formats, Helpers::Legacy
|
||||
|
||||
attr_reader :jobs
|
||||
|
||||
def initialize(jobs, options = {})
|
||||
@jobs = jobs
|
||||
end
|
||||
|
||||
def data
|
||||
jobs.map { |job| job_data(job) }
|
||||
end
|
||||
|
||||
def job_data(job)
|
||||
commit = job.commit
|
||||
{
|
||||
'id' => job.id,
|
||||
'repository_id' => job.repository_id,
|
||||
'number' => job.number,
|
||||
'state' => legacy_job_state(job),
|
||||
'queue' => job.queue,
|
||||
'allow_failure' => job.allow_failure
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -1,25 +1,21 @@
|
|||
module Travis
|
||||
module Api
|
||||
module V2
|
||||
module Http
|
||||
class Repository
|
||||
include Formats
|
||||
module Serialize
|
||||
module V1
|
||||
module Http
|
||||
class Repositories
|
||||
include Formats, Helpers::Legacy
|
||||
|
||||
attr_reader :repository, :options
|
||||
attr_reader :repositories
|
||||
|
||||
def initialize(repository, options = {})
|
||||
@repository = repository
|
||||
end
|
||||
def initialize(repositories, options = {})
|
||||
@repositories = repositories
|
||||
end
|
||||
|
||||
def data
|
||||
{
|
||||
'repo' => repository_data(repository)
|
||||
}
|
||||
end
|
||||
def data
|
||||
repositories.map { |repository| repository_data(repository) }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# TODO why does this not include the last build? (i.e. 'builds' => { last build here })
|
||||
def repository_data(repository)
|
||||
{
|
||||
'id' => repository.id,
|
||||
|
@ -27,17 +23,17 @@ module Travis
|
|||
'description' => repository.description,
|
||||
'last_build_id' => repository.last_build_id,
|
||||
'last_build_number' => repository.last_build_number,
|
||||
'last_build_state' => repository.last_build_state.to_s,
|
||||
'last_build_status' => legacy_repository_last_build_result(repository),
|
||||
'last_build_result' => legacy_repository_last_build_result(repository),
|
||||
'last_build_duration' => repository.last_build_duration,
|
||||
'last_build_language' => nil,
|
||||
'last_build_started_at' => format_date(repository.last_build_started_at),
|
||||
'last_build_finished_at' => format_date(repository.last_build_finished_at),
|
||||
'github_language' => repository.github_language
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,41 +1,34 @@
|
|||
module Travis
|
||||
module Api
|
||||
module V2
|
||||
module Http
|
||||
class Repositories
|
||||
include Formats
|
||||
module Serialize
|
||||
module V1
|
||||
module Http
|
||||
class Repository
|
||||
include Formats, Helpers::Legacy
|
||||
|
||||
attr_reader :repositories, :options
|
||||
attr_reader :repository, :options
|
||||
|
||||
def initialize(repositories, options = {})
|
||||
@repositories = repositories
|
||||
@options = options
|
||||
end
|
||||
def initialize(repository, options = {})
|
||||
@repository = repository
|
||||
end
|
||||
|
||||
def data
|
||||
{
|
||||
'repos' => repositories.map { |repository| repository_data(repository) }
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def repository_data(repository)
|
||||
def data
|
||||
{
|
||||
'id' => repository.id,
|
||||
'slug' => repository.slug,
|
||||
'description' => repository.description,
|
||||
'public_key' => repository.key.public_key,
|
||||
'last_build_id' => repository.last_build_id,
|
||||
'last_build_number' => repository.last_build_number,
|
||||
'last_build_state' => repository.last_build_state.to_s,
|
||||
'last_build_status' => legacy_repository_last_build_result(repository),
|
||||
'last_build_result' => legacy_repository_last_build_result(repository),
|
||||
'last_build_duration' => repository.last_build_duration,
|
||||
'last_build_language' => nil,
|
||||
'last_build_started_at' => format_date(repository.last_build_started_at),
|
||||
'last_build_finished_at' => format_date(repository.last_build_finished_at),
|
||||
'active' => repository.active,
|
||||
'github_language' => repository.github_language
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
33
lib/travis/api/serialize/v1/http/user.rb
Normal file
33
lib/travis/api/serialize/v1/http/user.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V1
|
||||
module Http
|
||||
class User
|
||||
include Formats
|
||||
|
||||
attr_reader :user, :options
|
||||
|
||||
def initialize(user, options = {})
|
||||
@user = user
|
||||
@options = options
|
||||
end
|
||||
|
||||
def data
|
||||
{
|
||||
'login' => user.login,
|
||||
'name' => user.name,
|
||||
'email' => user.email,
|
||||
'gravatar_id' => user.gravatar_id,
|
||||
'locale' => user.locale,
|
||||
'is_syncing' => user.is_syncing,
|
||||
'synced_at' => format_date(user.synced_at)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
1
lib/travis/api/serialize/v1/webhook.rb
Normal file
1
lib/travis/api/serialize/v1/webhook.rb
Normal file
|
@ -0,0 +1 @@
|
|||
require 'travis/api/serialize/v1/webhook/build'
|
29
lib/travis/api/serialize/v1/webhook/build.rb
Normal file
29
lib/travis/api/serialize/v1/webhook/build.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
require 'travis/api/serialize/v1/webhook/build/finished'
|
||||
|
||||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V1
|
||||
module Webhook
|
||||
class Build
|
||||
attr_reader :build, :commit, :request, :repository, :options
|
||||
|
||||
def initialize(build, options = {})
|
||||
@build = build
|
||||
@commit = build.commit
|
||||
@request = build.request
|
||||
@repository = build.repository
|
||||
@options = options
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def build_url
|
||||
["https://#{Travis.config.host}", repository.slug, 'builds', build.id].join('/')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
72
lib/travis/api/serialize/v1/webhook/build/finished.rb
Normal file
72
lib/travis/api/serialize/v1/webhook/build/finished.rb
Normal file
|
@ -0,0 +1,72 @@
|
|||
require 'travis/api/serialize/v1/webhook/build/finished/job'
|
||||
|
||||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V1
|
||||
module Webhook
|
||||
class Build
|
||||
class Finished < Build
|
||||
include Formats
|
||||
|
||||
def data
|
||||
data = {
|
||||
'id' => build.id,
|
||||
'repository' => repository_data,
|
||||
'number' => build.number,
|
||||
'config' => build.obfuscated_config.stringify_keys,
|
||||
'status' => build.result,
|
||||
'result' => build.result,
|
||||
'status_message' => result_message,
|
||||
'result_message' => result_message,
|
||||
'started_at' => format_date(build.started_at),
|
||||
'finished_at' => format_date(build.finished_at),
|
||||
'duration' => build.duration,
|
||||
'build_url' => build_url,
|
||||
'commit_id' => commit.id,
|
||||
'commit' => commit.commit,
|
||||
'base_commit' => request.base_commit,
|
||||
'head_commit' => request.head_commit,
|
||||
'branch' => commit.branch,
|
||||
'message' => commit.message,
|
||||
'compare_url' => commit.compare_url,
|
||||
'committed_at' => format_date(commit.committed_at),
|
||||
'author_name' => commit.author_name,
|
||||
'author_email' => commit.author_email,
|
||||
'committer_name' => commit.committer_name,
|
||||
'committer_email' => commit.committer_email,
|
||||
'matrix' => build.matrix.map { |job| Job.new(job, options).data },
|
||||
'type' => build.event_type,
|
||||
'state' => build.state.to_s,
|
||||
'pull_request' => build.pull_request?,
|
||||
'pull_request_number' => build.pull_request_number,
|
||||
'pull_request_title' => build.pull_request_title,
|
||||
'tag' => request.tag_name
|
||||
}
|
||||
|
||||
if commit.pull_request?
|
||||
data['pull_request_number'] = commit.pull_request_number
|
||||
end
|
||||
|
||||
data
|
||||
end
|
||||
|
||||
def repository_data
|
||||
{
|
||||
'id' => repository.id,
|
||||
'name' => repository.name,
|
||||
'owner_name' => repository.owner_name,
|
||||
'url' => repository.url
|
||||
}
|
||||
end
|
||||
|
||||
def result_message
|
||||
@result_message ||= ::Build::ResultMessage.new(build).short
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
52
lib/travis/api/serialize/v1/webhook/build/finished/job.rb
Normal file
52
lib/travis/api/serialize/v1/webhook/build/finished/job.rb
Normal file
|
@ -0,0 +1,52 @@
|
|||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V1
|
||||
module Webhook
|
||||
class Build
|
||||
class Finished < Build
|
||||
class Job
|
||||
include Formats
|
||||
|
||||
attr_reader :job, :commit, :options
|
||||
|
||||
def initialize(job, options = {})
|
||||
@job = job
|
||||
@commit = job.commit
|
||||
@options = options
|
||||
end
|
||||
|
||||
def data
|
||||
data = {
|
||||
'id' => job.id,
|
||||
'repository_id' => job.repository_id,
|
||||
'parent_id' => job.source_id,
|
||||
'number' => job.number,
|
||||
'state' => job.finished? ? 'finished' : job.state.to_s,
|
||||
'config' => job.obfuscated_config,
|
||||
'status' => job.result,
|
||||
'result' => job.result,
|
||||
'commit' => commit.commit,
|
||||
'branch' => commit.branch,
|
||||
'message' => commit.message,
|
||||
'compare_url' => commit.compare_url,
|
||||
'committed_at' => format_date(commit.committed_at),
|
||||
'author_name' => commit.author_name,
|
||||
'author_email' => commit.author_email,
|
||||
'committer_name' => commit.committer_name,
|
||||
'committer_email' => commit.committer_email,
|
||||
'allow_failure' => job.allow_failure
|
||||
}
|
||||
data['log'] = job.log_content || '' if options[:include_logs]
|
||||
data['started_at'] = format_date(job.started_at) if job.started?
|
||||
data['finished_at'] = format_date(job.finished_at) if job.finished?
|
||||
data
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
1
lib/travis/api/serialize/v2.rb
Normal file
1
lib/travis/api/serialize/v2.rb
Normal file
|
@ -0,0 +1 @@
|
|||
require 'travis/api/serialize/v2/http'
|
24
lib/travis/api/serialize/v2/http.rb
Normal file
24
lib/travis/api/serialize/v2/http.rb
Normal file
|
@ -0,0 +1,24 @@
|
|||
require 'travis/api/serialize/serializer'
|
||||
require 'travis/api/serialize/v2/http/accounts'
|
||||
require 'travis/api/serialize/v2/http/annotations'
|
||||
require 'travis/api/serialize/v2/http/broadcasts'
|
||||
require 'travis/api/serialize/v2/http/branch'
|
||||
require 'travis/api/serialize/v2/http/branches'
|
||||
require 'travis/api/serialize/v2/http/build'
|
||||
require 'travis/api/serialize/v2/http/builds'
|
||||
require 'travis/api/serialize/v2/http/caches'
|
||||
require 'travis/api/serialize/v2/http/hooks'
|
||||
require 'travis/api/serialize/v2/http/job'
|
||||
require 'travis/api/serialize/v2/http/jobs'
|
||||
require 'travis/api/serialize/v2/http/log'
|
||||
require 'travis/api/serialize/v2/http/permissions'
|
||||
require 'travis/api/serialize/v2/http/repositories'
|
||||
require 'travis/api/serialize/v2/http/repository'
|
||||
require 'travis/api/serialize/v2/http/requests'
|
||||
require 'travis/api/serialize/v2/http/request'
|
||||
require 'travis/api/serialize/v2/http/ssl_key'
|
||||
require 'travis/api/serialize/v2/http/env_var'
|
||||
require 'travis/api/serialize/v2/http/env_vars'
|
||||
require 'travis/api/serialize/v2/http/user'
|
||||
require 'travis/api/serialize/v2/http/validation_error'
|
||||
require 'travis/api/serialize/v2/http/ssh_key'
|
44
lib/travis/api/serialize/v2/http/accounts.rb
Normal file
44
lib/travis/api/serialize/v2/http/accounts.rb
Normal file
|
@ -0,0 +1,44 @@
|
|||
require 'travis/api/serialize/formats'
|
||||
|
||||
module Travis
|
||||
module Api
|
||||
module Serialize
|
||||
module V2
|
||||
module Http
|
||||
class Accounts
|
||||
include Formats
|
||||
|
||||
attr_reader :accounts, :options
|
||||
|
||||
def initialize(accounts, options = {})
|
||||
@accounts = accounts
|
||||
@options = options
|
||||
end
|
||||
|
||||
def data
|
||||
{
|
||||
:accounts => accounts.map { |account| account_data(account) }
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def account_data(account)
|
||||
data = {
|
||||
'id' => account.id,
|
||||
'name' => account.name,
|
||||
'login' => account.login,
|
||||
'type' => account.type.underscore,
|
||||
'repos_count' => account.repos_count
|
||||
}
|
||||
|
||||
data['avatar_url'] = account.avatar_url if account.respond_to?(:avatar_url)
|
||||
|
||||
data
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user