diff --git a/scripts/data-validate.js b/scripts/data-validate.js index 82874d3e..fce9aa36 100644 --- a/scripts/data-validate.js +++ b/scripts/data-validate.js @@ -1,8 +1,15 @@ import Joi from '@hapi/joi'; import core from '@actions/core'; +import * as http from 'http'; +import * as https from 'https'; import data from '../src/data.js'; import flags from './flags.js'; +if (process.env.CI !== 'true') { + core.error = console.error; + core.setFailed = console.error; +} + const schema = Joi.object({ name: Joi.string().required(), description: Joi.string().required(), @@ -33,3 +40,47 @@ errors.forEach(e => { if (errors.length) { core.setFailed('Action failed with validation errors, see logs'); } +const REQUEST_TIMEOUT = 10000; + +function getStatusCode(url) { + const client = url.startsWith('https') ? https : http; + return new Promise((resolve, reject) => { + setTimeout(() => reject(new Error('Request timed out')), REQUEST_TIMEOUT); + client + .get(url, res => { + resolve(res.statusCode); + }) + .on('error', err => { + reject(err); + }); + }); +} + +async function isWorkingUrl(url) { + try { + const statusCode = await getStatusCode(url); + if (statusCode < 200 || statusCode >= 400) { + core.error(`Ping to "${url}" failed with status: ${statusCode}`); + return false; + } + return true; + } catch (e) { + core.error(`Ping to "${url}" failed with error: ${e}`); + return false; + } +} + +(async () => { + // TODO: we might need to batch these in sets instead of requesting 100+ URLs + // at the same time + const areWorkingUrls = await Promise.all( + data.map(p => p.url).map(url => isWorkingUrl(url)) + ); + const failingUrls = areWorkingUrls.filter(a => !a); + if (failingUrls.length > 0) { + core.setFailed( + `Action failed with ${failingUrls.length} URL fetch failures, see logs` + ); + } + process.exit(0); +})(); diff --git a/src/data.js b/src/data.js index 08882927..b0276624 100644 --- a/src/data.js +++ b/src/data.js @@ -38,8 +38,7 @@ const pages = [ }, { name: 'Carter McAlister', - description: - 'Software Engineer, Digital Nomad, Lover of the Outdoors', + description: 'Software Engineer, Digital Nomad, Lover of the Outdoors', url: 'https://cartermcalister.dev/uses', twitter: '@_CarterMc_', emoji: '๐Ÿ”๏ธ', @@ -57,26 +56,19 @@ const pages = [ 'React', 'Node', 'CSS', - 'Java' + 'Java', ], }, { name: 'Matt Jennings', - description: - 'web dev, hockey | tradebreaker.io', + description: 'web dev, hockey | tradebreaker.io', url: 'https://mattjennings.io/uses', twitter: '@mattjennings44', emoji: '๐Ÿ’', country: '๐Ÿ‡จ๐Ÿ‡ฆ', computer: 'apple', phone: 'iphone', - tags: [ - 'Developer', - 'Full Stack', - 'JavaScript', - 'React', - 'Hockey' - ], + tags: ['Developer', 'Full Stack', 'JavaScript', 'React', 'Hockey'], }, { name: 'Jason Cory Alvernaz', @@ -121,21 +113,16 @@ const pages = [ ], }, { - name: 'Sam Cross', - description: '"Developer", IT student, frequent traveller by coach, addicted to music.', - url: 'https://sam-cross.github.io/uses', - twitter: '@samcrxss', - emoji: '๐ŸŽต', - country: '๐Ÿ‡ฌ๐Ÿ‡ง', - computer: 'windows', - phone: 'android', - tags: [ - 'Developer', - 'JavaScript', - 'React', - 'Node', - 'CSS', - ] + name: 'Sam Cross', + description: + '"Developer", IT student, frequent traveller by coach, addicted to music.', + url: 'https://sam-cross.github.io/uses', + twitter: '@samcrxss', + emoji: '๐ŸŽต', + country: '๐Ÿ‡ฌ๐Ÿ‡ง', + computer: 'windows', + phone: 'android', + tags: ['Developer', 'JavaScript', 'React', 'Node', 'CSS'], }, { name: 'Praveen Kumar Purushothaman', @@ -166,7 +153,7 @@ const pages = [ description: 'Developer Evangelist, JavaScript Developer, Cross-Platform App Developer and gamer', // URL to your /uses page - url: 'https://renepot.com/uses', + url: 'http://renepot.com/uses', twitter: '@wraldpyk', // An emoji that describes you emoji: '๐ŸŽฎ', @@ -220,29 +207,6 @@ const pages = [ 'Machine Learning', ], }, - { - name: 'Troy Forster', - description: 'Consulting Technology Director and CTO for Hire', - url: 'https://tforster.com/uses', - twitter: '@tforster', - emoji: '', - country: '๐Ÿ‡จ๐Ÿ‡ฆ', - computer: 'windows', - phone: 'android', - tags: [ - 'Engineer', - 'Back End', - 'Front End', - 'Consultant', - 'Entrepreneur', - 'JavaScript', - 'C#', - 'PHP', - 'Serverless', - 'SOA', - 'Enterprise', - ], - }, { name: 'Kent C. Dodds', description: 'JavaScript Software Engineer, speaker, and trainer', @@ -264,26 +228,6 @@ const pages = [ 'Blogger', ], }, - { - name: 'Hussain Aminu', - description: 'Web Developer, Data Scientist', - url: 'https://hussain4real.github.io/Portfolio/uses', - twitter: '@hussain4real', - emoji: '๐Ÿ”ฅ', - country: '๐Ÿ‡ณ๐Ÿ‡ฌ', - computer: 'windows', - phone: 'android', - tags: [ - 'Developer', - 'Full Stack', - 'Data Science', - 'JavaScript', - 'Python', - 'Vue', - 'Node', - 'Django', - ], - }, { name: 'Glenn Reyes', description: @@ -968,26 +912,6 @@ const pages = [ phone: 'android', tags: ['Designer', 'Entrepreneur'], }, - { - name: 'Sanket Gandhi', - description: 'Software Engineer', - url: 'https://sanketgandhi.com/uses', - twitter: '@sanketgandhi876', - emoji: '๐Ÿ”ฅ', - country: '๐Ÿ‡ฎ๐Ÿ‡ณ', - computer: 'apple', - phone: 'android', - tags: [ - 'Developer', - 'Full Stack', - 'PHP', - 'Laravel', - 'AWS', - 'JavaScript', - 'React', - 'Node', - ], - }, { name: 'Harry Wolff', description: 'Front-end engineer and YouTuber ', @@ -1109,25 +1033,6 @@ const pages = [ 'React', ], }, - { - name: 'Richard Palacios G.', - description: 'Web Developer, passionate apprentice, Community co-organizer', - url: 'https://www.richardpalaciosg.dev/uses', - twitter: '@rpalaciosg_', - emoji: 'โšก', - country: '๐Ÿ‡ช๐Ÿ‡จ', - computer: 'linux', - phone: 'android', - tags: [ - 'Developer', - 'JavaScript', - 'Front End', - 'BackEnd', - 'Community', - 'Node', - 'React', - ], - }, { name: 'Mike Barkmin', description: @@ -1429,27 +1334,6 @@ const pages = [ 'Open Source', ], }, - { - name: 'Martin Chammah', - description: 'Full Stack Gatsby Developer @ ecomerciar', - twitter: '@codigomate', - url: 'https://martinchammah.dev/uses', - emoji: '๐Ÿ‡ฆ๐Ÿ‡ท', - country: '๐Ÿ‡ฆ๐Ÿ‡ท', - computer: 'windows', - phone: 'android', - tags: [ - 'Developer', - 'Full Stack', - 'Entrepreneur', - 'YouTuber', - 'JavaScript', - 'Gatsby', - 'React', - 'Wordpress', - 'Thinkpad', - ], - }, { name: 'Pedro Assunรงรฃo', description: 'Senior Fullstack Software Developer, Tutorial Maker, Blogger', @@ -1474,27 +1358,6 @@ const pages = [ 'AWS', ], }, - { - name: 'Marek Racรญk', - description: 'Full Stack Developer', - url: 'https://racik.info/uses', - twitter: '@marek_racik', - emoji: '๐Ÿ', - country: '๐Ÿ‡ธ๐Ÿ‡ฐ', - computer: 'apple', - phone: 'iphone', - tags: [ - 'Web Developer', - 'Full Stack', - 'Laravel', - 'Vue', - 'Tailwind', - 'Django', - 'Python', - 'PHP', - 'JavaScript', - ], - }, { name: 'Steven van Loef', description: 'Web Developer, App Developer', @@ -1642,17 +1505,6 @@ const pages = [ 'Golang', ], }, - { - name: 'Juan Manuel Incaurgarat', - description: 'Front end developer', - url: 'https://kilinkis.me/uses', - twitter: '@kilinkis', - emoji: '๐Ÿ€', - country: '๐Ÿ‡ฆ๐Ÿ‡ท', - computer: 'apple', - phone: 'android', - tags: ['React', 'WordPress', 'Gatsby', 'JavaScript', 'Node'], - }, { name: 'Jared Clifton-Lee', description: 'Engineer of code; manager of people; trainer of cats', @@ -1676,28 +1528,6 @@ const pages = [ 'Node', ], }, - { - name: 'Carlos Junod', - description: - 'Husband, Dreamer, Full Stack Developer, Javascript passionate, Graphic Designer', - url: 'http://carlosjunod.me/uses/', - twitter: '@carlosjunod', - emoji: '๐Ÿฅ‘', - country: '๐Ÿ‡จ๐Ÿ‡ฑ', - computer: 'apple', - phone: 'iphone', - tags: [ - 'Developer', - 'Full Stack', - 'React', - 'Designer', - 'Entrepreneur', - 'JavaScript', - 'Node', - 'CSS', - 'HTML', - ], - }, { name: 'James Kemp', description: 'Web Developer, Blogger, Freelancer', @@ -1737,30 +1567,6 @@ const pages = [ 'Podcaster', ], }, - { - name: 'Khriztian Moreno', - description: - '#Javascript Developer ๐Ÿฅ‘& Community builder ๐Ÿ‘จ๐Ÿปโ€๐Ÿ’ปโ™ฅ๏ธ๐Ÿ‘จ๐Ÿปโ€๐Ÿซ | #MDE at @cloudinary | Producer @commitfm ๐ŸŽ™๐Ÿ“ป | Co-Organize of @MedellinJS @avanetr', - url: 'https://khriztianmoreno.dev/uses', - twitter: '@khriztianmoreno', - emoji: '๐Ÿ‘จ๐Ÿผโ€๐Ÿ’ป', - country: '๐Ÿ‡จ๐Ÿ‡ด', - computer: 'apple', - phone: 'iphone', - tags: [ - 'Developer', - 'JavaScript', - 'React', - 'Front End', - 'React', - 'Blogger', - 'Speaker', - 'Podcaster', - 'Community', - 'JAMstack', - 'YouTuber', - ], - }, { name: 'Mihai Serban', description: @@ -1847,27 +1653,6 @@ const pages = [ 'JavaScript', ], }, - { - name: 'Yuri Yakovlev', - description: - 'Maker of this site. Web Developer, Tutorial Maker, Podcaster, BBQ Lover', - url: 'https://mynameisyuri.com/uses', - twitter: '@yakovlevyuri', - emoji: '๐Ÿง™โ€โ™‚๏ธ', - country: '๐Ÿ‡จ๐Ÿ‡ฟ', - computer: 'apple', - phone: 'iphone', - tags: [ - 'Developer', - 'Full Stack', - 'Serverless', - 'JavaScript', - 'TypeScript', - 'React', - 'Node', - 'GraphQL', - ], - }, { name: 'Josรฉ Carlos Correa', description: @@ -1910,29 +1695,6 @@ const pages = [ 'Azure', ], }, - { - name: 'Carlos Andres Charris Sandoval', - description: 'Software Engineer', - url: 'https://carloscharris.com/uses', - twitter: '@Darkklitos', - emoji: '๐Ÿ”ฅ', - country: '๐Ÿ‡จ๐Ÿ‡ด', - computer: 'apple', - phone: 'android', - tags: [ - 'Developer', - 'Full Stack', - 'JavaScript', - 'TypeScript', - 'Angular', - 'Vue', - 'React', - 'Node', - 'Java', - 'Docker', - 'Serverless', - ], - }, { name: 'Juanito Fatas', description: 'Program Tinker ๐Ÿง™๐Ÿผโ€โ™‚๏ธ', @@ -1944,30 +1706,6 @@ const pages = [ phone: 'iphone', tags: ['Think', 'Apply'], }, - { - name: 'ร†ndrew Rininsland', - description: 'Developer-Journalist', - url: 'https://aendrew.com/uses', - twitter: '@aendrew', - emoji: '๐Ÿ’š', - country: '๐Ÿณ๏ธโ€๐ŸŒˆ', - computer: 'apple', - phone: 'android', - tags: [ - 'Developer', - 'DataViz', - 'JavaScript', - 'TypeScript', - 'Node', - 'Python', - 'Author', - 'Journalist', - 'Speaker', - 'Front-End', - 'React', - 'D3', - ], - }, { name: 'Elliot Bonneville', description: @@ -2063,19 +1801,11 @@ const pages = [ country: '๐Ÿ‡ฒ๐Ÿ‡ฝ', computer: 'linux', phone: 'android', - tags: [ - 'Developer', - 'Full Stack', - 'PHP', - 'JavaScript', - 'Laravel', - 'React', - ], + tags: ['Developer', 'Full Stack', 'PHP', 'JavaScript', 'Laravel', 'React'], }, { name: 'Oscar Sรกnchez', - description: - 'Passionate developer, traveler and drummer from Perรบ', + description: 'Passionate developer, traveler and drummer from Perรบ', url: 'https://devlusaja.com', twitter: '@dev_lusaja', emoji: '๐Ÿ’ป๐Ÿ›ฉ๐Ÿ’ช', @@ -2090,7 +1820,7 @@ const pages = [ 'Docker', 'Graphql', 'AWS', - 'Open Source' + 'Open Source', ], }, { @@ -2102,7 +1832,15 @@ const pages = [ country: '๐Ÿ‡ฉ๐Ÿ‡ช', computer: 'apple', phone: 'iphone', - tags: ['JavaScript', 'React', 'Blogger', 'GraphQL', 'serverless', 'Node', 'Full Stack'] + tags: [ + 'JavaScript', + 'React', + 'Blogger', + 'GraphQL', + 'serverless', + 'Node', + 'Full Stack', + ], }, { name: 'Philip Theobald', @@ -2113,12 +1851,7 @@ const pages = [ country: '๐Ÿ‡บ๐Ÿ‡ธ', computer: 'apple', phone: 'android', - tags: [ - 'Software Engineer', - 'Laravel', - 'Vue', - 'WordPress' - ], + tags: ['Software Engineer', 'Laravel', 'Vue', 'WordPress'], }, { name: 'Alejandro G. Anglada', @@ -2147,22 +1880,14 @@ const pages = [ }, { name: 'Antoni Kepinski', - description: - 'Node Fetch maintainer // Into Node.js and Rust', + description: 'Node Fetch maintainer // Into Node.js and Rust', url: 'https://kepinski.me/uses/', twitter: '@dokwadratu', emoji: 'โšก', country: '๐Ÿ‡ต๐Ÿ‡ฑ', computer: 'linux', phone: 'iphone', - tags: [ - 'JavaScript', - 'Developer', - 'TypeScript', - 'React', - 'Rust', - 'Node' - ], + tags: ['JavaScript', 'Developer', 'TypeScript', 'React', 'Rust', 'Node'], }, { name: 'Marcus Obst', @@ -2172,14 +1897,7 @@ const pages = [ country: '๐Ÿ‡ฉ๐Ÿ‡ช', computer: 'windows', phone: 'iphone', - tags: [ - 'Developer', - 'Full Stack', - 'PHP', - 'JavaScript', - 'CSS', - 'Vue' - ], + tags: ['Developer', 'Full Stack', 'PHP', 'JavaScript', 'CSS', 'Vue'], }, { name: 'Pawel Grzybek', @@ -2204,7 +1922,8 @@ const pages = [ }, { name: 'Eric McCormick', - description: 'Software Developer, IBM Champion, coffee lover, dabbler in all things technology, hobbyist 3d design and printing', + description: + 'Software Developer, IBM Champion, coffee lover, dabbler in all things technology, hobbyist 3d design and printing', url: 'https://edm00se.codes/uses/', twitter: '@edm00se', emoji: '๐Ÿค”', @@ -2221,7 +1940,7 @@ const pages = [ 'Vue', 'Node', 'CSS', - ] + ], }, { name: 'Ben Congdon', @@ -2246,3 +1965,275 @@ const pages = [ ]; export default pages; +// Times out +// { +// name: 'Troy Forster', +// description: 'Consulting Technology Director and CTO for Hire', +// url: 'https://tforster.com/uses', +// twitter: '@tforster', +// emoji: '', +// country: '๐Ÿ‡จ๐Ÿ‡ฆ', +// computer: 'windows', +// phone: 'android', +// tags: [ +// 'Engineer', +// 'Back End', +// 'Front End', +// 'Consultant', +// 'Entrepreneur', +// 'JavaScript', +// 'C#', +// 'PHP', +// 'Serverless', +// 'SOA', +// 'Enterprise', +// ], +// }, + +// No /uses page (404) +// { +// name: 'Hussain Aminu', +// description: 'Web Developer, Data Scientist', +// url: 'https://hussain4real.github.io/Portfolio/uses', +// twitter: '@hussain4real', +// emoji: '๐Ÿ”ฅ', +// country: '๐Ÿ‡ณ๐Ÿ‡ฌ', +// computer: 'windows', +// phone: 'android', +// tags: [ +// 'Developer', +// 'Full Stack', +// 'Data Science', +// 'JavaScript', +// 'Python', +// 'Vue', +// 'Node', +// 'Django', +// ], +// }, + +// No /uses page +// { +// name: 'Sanket Gandhi', +// description: 'Software Engineer', +// url: 'https://sanketgandhi.com/uses', +// twitter: '@sanketgandhi876', +// emoji: '๐Ÿ”ฅ', +// country: '๐Ÿ‡ฎ๐Ÿ‡ณ', +// computer: 'apple', +// phone: 'android', +// tags: [ +// 'Developer', +// 'Full Stack', +// 'PHP', +// 'Laravel', +// 'AWS', +// 'JavaScript', +// 'React', +// 'Node', +// ], +// }, + +// No /uses page +// { +// name: 'Martin Chammah', +// description: 'Full Stack Gatsby Developer @ ecomerciar', +// twitter: '@codigomate', +// url: 'https://martinchammah.dev/uses', +// emoji: '๐Ÿ‡ฆ๐Ÿ‡ท', +// country: '๐Ÿ‡ฆ๐Ÿ‡ท', +// computer: 'windows', +// phone: 'android', +// tags: [ +// 'Developer', +// 'Full Stack', +// 'Entrepreneur', +// 'YouTuber', +// 'JavaScript', +// 'Gatsby', +// 'React', +// 'Wordpress', +// 'Thinkpad', +// ], +// }, + +// No /uses page +// { +// name: 'Richard Palacios G.', +// description: 'Web Developer, passionate apprentice, Community co-organizer', +// url: 'https://www.richardpalaciosg.dev/uses', +// twitter: '@rpalaciosg_', +// emoji: 'โšก', +// country: '๐Ÿ‡ช๐Ÿ‡จ', +// computer: 'linux', +// phone: 'android', +// tags: [ +// 'Developer', +// 'JavaScript', +// 'Front End', +// 'BackEnd', +// 'Community', +// 'Node', +// 'React', +// ], +// }, + +// No /uses page +// { +// name: 'Marek Racรญk', +// description: 'Full Stack Developer', +// url: 'https://racik.info/uses', +// twitter: '@marek_racik', +// emoji: '๐Ÿ', +// country: '๐Ÿ‡ธ๐Ÿ‡ฐ', +// computer: 'apple', +// phone: 'iphone', +// tags: [ +// 'Web Developer', +// 'Full Stack', +// 'Laravel', +// 'Vue', +// 'Tailwind', +// 'Django', +// 'Python', +// 'PHP', +// 'JavaScript', +// ], +// }, + +// Weird redirect to YouTube Video +// { +// name: 'Juan Manuel Incaurgarat', +// description: 'Front end developer', +// url: 'https://kilinkis.me/uses', +// twitter: '@kilinkis', +// emoji: '๐Ÿ€', +// country: '๐Ÿ‡ฆ๐Ÿ‡ท', +// computer: 'apple', +// phone: 'android', +// tags: ['React', 'WordPress', 'Gatsby', 'JavaScript', 'Node'], +// }, + +// DEAD site +// { +// name: 'Carlos Junod', +// description: +// 'Husband, Dreamer, Full Stack Developer, Javascript passionate, Graphic Designer', +// url: 'http://carlosjunod.me/uses/', +// twitter: '@carlosjunod', +// emoji: '๐Ÿฅ‘', +// country: '๐Ÿ‡จ๐Ÿ‡ฑ', +// computer: 'apple', +// phone: 'iphone', +// tags: [ +// 'Developer', +// 'Full Stack', +// 'React', +// 'Designer', +// 'Entrepreneur', +// 'JavaScript', +// 'Node', +// 'CSS', +// 'HTML', +// ], +// }, + +// No /uses page +// { +// name: 'Khriztian Moreno', +// description: +// '#Javascript Developer ๐Ÿฅ‘& Community builder ๐Ÿ‘จ๐Ÿปโ€๐Ÿ’ปโ™ฅ๏ธ๐Ÿ‘จ๐Ÿปโ€๐Ÿซ | #MDE at @cloudinary | Producer @commitfm ๐ŸŽ™๐Ÿ“ป | Co-Organize of @MedellinJS @avanetr', +// url: 'https://khriztianmoreno.dev/uses', +// twitter: '@khriztianmoreno', +// emoji: '๐Ÿ‘จ๐Ÿผโ€๐Ÿ’ป', +// country: '๐Ÿ‡จ๐Ÿ‡ด', +// computer: 'apple', +// phone: 'iphone', +// tags: [ +// 'Developer', +// 'JavaScript', +// 'React', +// 'Front End', +// 'React', +// 'Blogger', +// 'Speaker', +// 'Podcaster', +// 'Community', +// 'JAMstack', +// 'YouTuber', +// ], +// }, + +// No /uses page +// { +// name: 'Yuri Yakovlev', +// description: +// 'Maker of this site. Web Developer, Tutorial Maker, Podcaster, BBQ Lover', +// url: 'https://mynameisyuri.com/uses', +// twitter: '@yakovlevyuri', +// emoji: '๐Ÿง™โ€โ™‚๏ธ', +// country: '๐Ÿ‡จ๐Ÿ‡ฟ', +// computer: 'apple', +// phone: 'iphone', +// tags: [ +// 'Developer', +// 'Full Stack', +// 'Serverless', +// 'JavaScript', +// 'TypeScript', +// 'React', +// 'Node', +// 'GraphQL', +// ], +// }, + +// Times out +// { +// name: 'Carlos Andres Charris Sandoval', +// description: 'Software Engineer', +// url: 'https://carloscharris.com/uses', +// twitter: '@Darkklitos', +// emoji: '๐Ÿ”ฅ', +// country: '๐Ÿ‡จ๐Ÿ‡ด', +// computer: 'apple', +// phone: 'android', +// tags: [ +// 'Developer', +// 'Full Stack', +// 'JavaScript', +// 'TypeScript', +// 'Angular', +// 'Vue', +// 'React', +// 'Node', +// 'Java', +// 'Docker', +// 'Serverless', +// ], +// }, + +// Empty /uses page +// { +// name: 'ร†ndrew Rininsland', +// description: 'Developer-Journalist', +// url: 'https://aendrew.com/uses', +// twitter: '@aendrew', +// emoji: '๐Ÿ’š', +// country: '๐Ÿณ๏ธโ€๐ŸŒˆ', +// computer: 'apple', +// phone: 'android', +// tags: [ +// 'Developer', +// 'DataViz', +// 'JavaScript', +// 'TypeScript', +// 'Node', +// 'Python', +// 'Author', +// 'Journalist', +// 'Speaker', +// 'Front-End', +// 'React', +// 'D3', +// ], +// },