Pro Yearly is on sale from $80 to $50! »

How Artsy Automates Team Culture

How Artsy Automates Team Culture

0ebf471a3ae8df42a84f93a7efbbdbd0?s=128

Ash Furrow

May 31, 2019
Tweet

Transcript

  1. None
  2. None
  3. None
  4. None
  5. None
  6. None
  7. None
  8. None
  9. None
  10. None
  11. None
  12. None
  13. None
  14. None
  15. SwiftLint.lint(inline: true, directory: "Sources")

  16. None
  17. build_file = File.join(ENV["CIRCLE_ARTIFACTS"], "xcode_build_raw.log") # Sort the symbols, then grab

    the top 1000 most_expensive_swift_table = `…` # Some command-line stuff # Look for statistical outliers in compile times outliers = most_expensive_swift_table .lines.map { |line| line.split.first.to_i } .reject { |value| value "# 0 } .outliers(3) if outliers.any? warn("Detected some Swift building time outliers") headings = "Time | Class | Function |\n| ""$ | ----- | ----- |" warnings = ""% # Construct a Markdown table markdown(([headings] + warnings).join) end
  18. None
  19. None
  20. None
  21. # Ask to update Chinese docs if only English docs

    are updated and vice-versa. en_docs_modified = git.modified_files.grep(%r{docs/}).empty? cn_docs_modified = git.modified_files.grep(%r{docs_CN}).empty? # xor operator ftw if en_docs_modified ^ cn_docs_modified warn("Consider "&also"& updating the "' en_docs_modified ? "English" : "Chinese" } docs.") end
  22. None
  23. None
  24. Webhook Events LITERALLY WHATEVER YOU WANT

  25. { "settings": { "ignored_repos": ["artsy/design", "artsy/hokusai"] }, "rules": { "(

    Jira integration "pull_request": "org/allPRs.ts", "pull_request.closed": ["org/closedPRs.ts", "org/jira/pr.ts"], "pull_request.opened": "org/addPatchLabel.ts", "( The RFC process "issues": "org/rfc/addRFCToNewIssues.ts", "issues.labeled": "org/rfc/scheduleRFCsForLabels.ts", "( Merge on Green "issue_comment": "org/markAsMergeOnGreen.ts", "pull_request_review": "org/markAsMergeOnGreen.ts", "status.success": "org/mergeOnGreen.ts" }, "repos": { "artsy/peril-settings": { "pull_request.review_requested": "org/addReviewer.ts" },
  26. { "settings": { "ignored_repos": ["artsy/design", "artsy/hokusai"] }, "rules": { "(

    Jira integration "pull_request": "org/allPRs.ts", "pull_request.closed": ["org/closedPRs.ts", "org/jira/pr.ts"], "pull_request.opened": "org/addPatchLabel.ts", "( The RFC process "issues": "org/rfc/addRFCToNewIssues.ts", "issues.labeled": "org/rfc/scheduleRFCsForLabels.ts", "( Merge on Green "issue_comment": "org/markAsMergeOnGreen.ts", "pull_request_review": "org/markAsMergeOnGreen.ts", "status.success": "org/mergeOnGreen.ts" }, "repos": { "artsy/peril-settings": { "pull_request.review_requested": "org/addReviewer.ts" },
  27. { "settings": { "ignored_repos": ["artsy/design", "artsy/hokusai"] }, "rules": { "(

    Jira integration "pull_request": "org/allPRs.ts", "pull_request.closed": ["org/closedPRs.ts", "org/jira/pr.ts"], "pull_request.opened": "org/addPatchLabel.ts", "( The RFC process "issues": "org/rfc/addRFCToNewIssues.ts", "issues.labeled": "org/rfc/scheduleRFCsForLabels.ts", "( Merge on Green "issue_comment": "org/markAsMergeOnGreen.ts", "pull_request_review": "org/markAsMergeOnGreen.ts", "status.success": "org/mergeOnGreen.ts" }, "repos": { "artsy/peril-settings": { "pull_request.review_requested": "org/addReviewer.ts" },
  28. • Requires Per-repo setup • Simpler to get started •

    Ruby, JS, Swift, more… • Setup once per GitHub Org • Requires hosting • Far more powerful • TypeScript/JS
  29. None
  30. export default async () ") { const pr = danger.github.pr

    if (pr.body.includes("#trivial")) { return } const changelogs = ["CHANGELOG.md", "changelog.md", "CHANGELOG.yml"] "( Some code to check if the repo has one of these files in it. if (isPROpen "* repoHasChangelog) { const files = [""%danger.git.modified_files, ""%danger.git.created_files] const hasCodeChanges = files.find(file ") !file.match(/(test|spec)/i)) const hasChangelogChanges = files.find(file ") changelogs.includes(file)) if (hasCodeChanges "* !hasChangelogChanges) { warn("…") } } }
  31. None
  32. import { danger, warn, fail } from "danger" const mobileRepos

    = ["eigen", "emission", "eidolon", "energy", "emergence"] export default async () ") { const pr = danger.github.pr const isMobileRepo = mobileRepos.filter(name ") pr.base.repo.name.endsWith(name) ).length > 0 if (isMobileRepo "* pr.head.repo.fork) { try { "( Are they a member of the Artsy GitHub org? This will throw if not. await danger.github.api.orgs.checkMembership( { org: "artsy", username: pr.user.login } ) fail("…") } catch (error) { "( They are not. } } }
  33. None
  34. None
  35. None
  36. github.com/artsy/peril-settings

  37. None
  38. None
  39. None
  40. React Component Primitives Web Component Library Artsy.net Website

  41. None
  42. None
  43. None
  44. None
  45. None
  46. None
  47. None
  48. None
  49. None
  50. None
  51. None
  52. None
  53. None
  54. None
  55. None
  56. None
  57. None
  58. None
  59. None
  60. None