Skip to content

Commit

Permalink
Migrate to github actions (#312)
Browse files Browse the repository at this point in the history
* ci: switch to github actions

* ci: move actions into workflows/

* ci: rename link checking ci job

* docs: add a badge for gha link checker

* ci: attempt to enable actions on PRs
  • Loading branch information
zevisert authored Feb 29, 2024
1 parent 5e04e39 commit 222f00b
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 80 deletions.
72 changes: 72 additions & 0 deletions .github/workflows/link-checker.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: Link Checking

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
check-links:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y curl bash ca-certificates
- name: Find Comment
uses: peter-evans/find-comment@v3
id: fc
if: github.event_name == 'pull_request'
with:
issue-number: ${{ github.event.pull_request.number }}
comment-author: "github-actions[bot]"
body-includes: <!-- link-checker -->

- name: Check links
id: report
run: bash link_checker/check.sh README.md --markdown > report.md

# An existing comment now has no issues
- name: Clear report
if: ${{ github.event_name == 'pull_request' && steps.fc.outputs.comment-id != '' }}
uses: peter-evans/create-or-update-comment@v4
with:
comment-id: ${{ steps.fc.outputs.comment-id }}
edit-mode: replace
body: |
<!-- link-checker -->
Link checker still sees no broken links, all good! :tada:
# No existing comment, and no issues found
- name: No issues
if: ${{ github.event_name == 'pull_request' && steps.fc.outputs.comment-id == '' }}
uses: peter-evans/create-or-update-comment@v4
with:
issue-number: ${{ github.event.pull_request.number }}
body: |
<!-- link-checker -->
Link checker found no broken links! :sparkles:
# No existing comment, but issues found
- name: Create new report
if: ${{ failure() && github.event_name == 'pull_request' && steps.report.conclusion == 'failure' && steps.fc.outputs.comment-id == '' }}
uses: peter-evans/create-or-update-comment@v4
with:
issue-number: ${{ github.event.pull_request.number }}
body-path: "report.md"

# Update existing comment with new report
- name: Update report
if: ${{ failure() && github.event_name == 'pull_request' && steps.report.conclusion == 'failure' && steps.fc.outputs.comment-id != '' }}
uses: peter-evans/create-or-update-comment@v4
with:
comment-id: ${{ steps.fc.outputs.comment-id }}
edit-mode: replace
body-path: report.md
13 changes: 0 additions & 13 deletions .travis.yml

This file was deleted.

100 changes: 59 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,44 +6,53 @@ A well-maintained list of available startup jobs in Victoria BC. This list is cu

[Tweet about us!][tweet-link]

[![Build Status](https://travis-ci.com/sendwithus/vic-startup-jobs.svg?branch=main)](https://app.travis-ci.com/sendwithus/vic-startup-jobs)
[![Link Checking](https://github.com/sendwithus/vic-startup-jobs/actions/workflows/link-checker.yaml/badge.svg?branch=main)](https://github.com/sendwithus/vic-startup-jobs/actions/workflows/link-checker.yaml)

### How to Apply?

Click the link for more info about each job posting, including how to apply. Most companies provide application instructions on their websites.

### How to Post?

Posting is easy and free, simply fork this repo and submit a pull request adding/updating your job posting. Avoid generic "call for resumes" and prefer specific job postings. If you have questions, need help, or want us to update the list for you, please email [email protected].

Note that there is a CI hook that runs after PR creation that checks for any 404s links on this page. You can run it manually prior to pushing:

```
link_checker/check.sh README.md
```

Running it before pushing up to Github allows you to remove broken job links from the list in addition to updating your own job postings. More info on the [associated README](/link_checker/README.md)

### Who can post?

Tech startups with offices in Victoria BC. If we notice that you haven't posted a role in ~6 months, we may remove your org from the list in order to keep it up-to-date. Email us when you have a job and we can re-add you!

### What about Co-Op & Intern Friendly Companies?
Companies that are known for hiring/placing co-op students and interns will have a `(πŸ‘©β€πŸ’» Co-Op / Intern Friendly)` following their name. These companies are always open to discussing opportunities for students and aspiring developers, designers, and marketers.

Companies that are known for hiring/placing co-op students and interns will have a `(πŸ‘©β€πŸ’» Co-Op / Intern Friendly)` following their name. These companies are always open to discussing opportunities for students and aspiring developers, designers, and marketers.

### How can I get involved in the Victoria tech community?
* Connect with the Victoria tech community by joining the [YYJ Tech Slack group](https://yyj-tech.ca/)
* Connect with the Victoria ladies tech community by joining the [YYJ Tech Ladies Slack group](http://yyjtechladies.com/). Please note that this group is for anyone who is female.

- Connect with the Victoria tech community by joining the [YYJ Tech Slack group](https://yyj-tech.ca/)
- Connect with the Victoria ladies tech community by joining the [YYJ Tech Ladies Slack group](http://yyjtechladies.com/). Please note that this group is for anyone who is female.

## Current Job Openings

Keep in mind that companies may have job postings on their own site that are not listed here - you should visit them and look for opportunities. Also, many companies are open to being contacted directly about opportunities, even if it's only to keep your resume on file.
Keep in mind that companies may have job postings on their own site that are not listed here - you should visit them and look for opportunities. Also, many companies are open to being contacted directly about opportunities, even if it's only to keep your resume on file.

#### [Advanced Solutions](https://dxcas.com/index.php/careers/current-opportunities)
*[Chief Technology Officer](https://dxcas.com/index.php/careers/current-opportunities)
*[Director of Finance, Account Finance Lead](https://dxcas.com/index.php/careers/current-opportunities)
*[Senior Database Administrator (Oracle)](https://dxcas.com/index.php/careers/current-opportunities)
*[Open VMS Administrator](https://dxcas.com/index.php/careers/current-opportunities)

_[Chief Technology Officer](https://dxcas.com/index.php/careers/current-opportunities)
_[Director of Finance, Account Finance Lead](https://dxcas.com/index.php/careers/current-opportunities)
_[Senior Database Administrator (Oracle)](https://dxcas.com/index.php/careers/current-opportunities)
_[Open VMS Administrator](https://dxcas.com/index.php/careers/current-opportunities)

#### [AlayaCare](https://www.alayacare.com/)

#### [Animikii](https://www.animikii.com/?utm_source=careers&utm_medium=website&utm_campaign=quote_contact&utm_content=logo)
* [Senior Full Stack Web Developer](https://animikii.applytojobs.ca/software/26682)

- [Senior Full Stack Web Developer](https://animikii.applytojobs.ca/software/26682)

#### [Audette](https://www.audette.io/)

Expand All @@ -52,12 +61,14 @@ Keep in mind that companies may have job postings on their own site that are not
#### [Bambora North America/Worldline](https://www.bambora.com/en/ca/) (πŸ‘©β€πŸ’» Co-Op / Intern Friendly)

#### [Barnacle Systems](https://brnkl.io/) (πŸ‘©β€πŸ’» Co-Op / Intern Friendly)
* [Intermediate Front-End Developer](https://www.brnkl.io/careers)
* [Intermediate/Senior Full-Stack Developer](https://www.brnkl.io/careers)
* [IoT Systems & Mobile App Test Engineer - Co-op](https://www.brnkl.io/careers)

#### [Benevity](https://www.benevity.com/) (πŸ‘©β€πŸ’» Co-Op / Intern Friendly)
* [Director of Engineering & Analytics](https://benevity.com/job-postings?gh_jid=4945359004)
- [Intermediate Front-End Developer](https://www.brnkl.io/careers)
- [Intermediate/Senior Full-Stack Developer](https://www.brnkl.io/careers)
- [IoT Systems & Mobile App Test Engineer - Co-op](https://www.brnkl.io/careers)

#### [Benevity](https://www.benevity.com/) (πŸ‘©β€πŸ’» Co-Op / Intern Friendly)

- [Director of Engineering & Analytics](https://benevity.com/job-postings?gh_jid=4945359004)

#### [Button](https://button.is/careers)

Expand Down Expand Up @@ -102,39 +113,43 @@ Keep in mind that companies may have job postings on their own site that are not
#### [KIXEYE Canada Ltd](https://www.kixeye.com/)

#### [VertiGIS](https://vertigisstudio.com/) (πŸ‘©β€πŸ’» Co-Op / Intern Friendly)
* [Solutions Architect](https://vertigis.bamboohr.com/careers/122)

- [Solutions Architect](https://vertigis.bamboohr.com/careers/122)

#### [LlamaZOO](https://www.llamazoo.com/) (πŸ‘©β€πŸ’» Co-Op / Intern Friendly)

#### [MetaLab](https://metalab.co/) (πŸ‘©β€πŸ’» Co-Op / Intern Friendly)
* [Principal Engineer, Machine Learning](https://www.metalab.com/careers#current-openings)
* [Design Technologist](https://www.metalab.com/careers#current-openings)
* [Senior Full Stack Developer, Machine Learning](https://www.metalab.com/careers#current-openings)
* [Principal Architect](https://www.metalab.com/careers#current-openings)
* [Director, Client Services](https://www.metalab.com/careers#current-openings)
* [Director, Finance (FP&A)](https://www.metalab.com/careers#current-openings)
* [Senior Full Stack Developer](https://www.metalab.com/careers#current-openings)
* [Principal Engineer](https://www.metalab.com/careers#current-openings)
* [Executive Assistant](https://www.metalab.com/careers#current-openings)
* [Partnerships Director](https://www.metalab.com/careers#current-openings)
* [Principal Visual Designer](https://www.metalab.com/careers#current-openings)
* [Brand Designer](https://www.metalab.com/careers#current-openings)
* [Design Lead](https://www.metalab.com/careers#current-openings)
* [Senior Design Director](https://www.metalab.com/careers#current-openings)

- [Principal Engineer, Machine Learning](https://www.metalab.com/careers#current-openings)
- [Design Technologist](https://www.metalab.com/careers#current-openings)
- [Senior Full Stack Developer, Machine Learning](https://www.metalab.com/careers#current-openings)
- [Principal Architect](https://www.metalab.com/careers#current-openings)
- [Director, Client Services](https://www.metalab.com/careers#current-openings)
- [Director, Finance (FP&A)](https://www.metalab.com/careers#current-openings)
- [Senior Full Stack Developer](https://www.metalab.com/careers#current-openings)
- [Principal Engineer](https://www.metalab.com/careers#current-openings)
- [Executive Assistant](https://www.metalab.com/careers#current-openings)
- [Partnerships Director](https://www.metalab.com/careers#current-openings)
- [Principal Visual Designer](https://www.metalab.com/careers#current-openings)
- [Brand Designer](https://www.metalab.com/careers#current-openings)
- [Design Lead](https://www.metalab.com/careers#current-openings)
- [Senior Design Director](https://www.metalab.com/careers#current-openings)

#### [Momentum Dashboard](https://momentumdash.com/) (πŸ‘©β€πŸ’» Co-Op / Intern Friendly)
* [Senior Front-End Developer](https://momentumdash.com/careers/#front-end-developer)
* [Full Stack Developer](https://momentumdash.com/careers/#product-designer)

- [Senior Front-End Developer](https://momentumdash.com/careers/#front-end-developer)
- [Full Stack Developer](https://momentumdash.com/careers/#product-designer)

#### [MonetizeMore](https://www.monetizemore.com/)

#### [OneFeather](https://www.onefeather.ca/)

#### [One Net Inc](https://www.onenetinc.com/crew#Careers)
* [Mobile Developer:Swift](https://www.onenetinc.com/careers/mobile-developer-swift)
* [Android Developer:Java](https://www.onenetinc.com/careers/mobile-developer-java)
* [Digital Media Buyer](https://www.onenetinc.com/careers/digital-media-buyer)
* [Account Strategist(Remote)](https://www.onenetinc.com/careers/account-strategist-remote)

- [Mobile Developer:Swift](https://www.onenetinc.com/careers/mobile-developer-swift)
- [Android Developer:Java](https://www.onenetinc.com/careers/mobile-developer-java)
- [Digital Media Buyer](https://www.onenetinc.com/careers/digital-media-buyer)
- [Account Strategist(Remote)](https://www.onenetinc.com/careers/account-strategist-remote)

#### [Othersphere](https://www.othersphere.io/)

Expand All @@ -147,8 +162,9 @@ Keep in mind that companies may have job postings on their own site that are not
#### [Redbrick](https://rdbrck.com/) (πŸ‘©β€πŸ’» Co-Op / Intern Friendly)

#### [Regroove](https://regroove.ca) (πŸ‘©β€πŸ’» Co-Op / Intern Friendly)
* [Cloud Solutions Consultant](https://regroove.ca/careers/cloud-solutions-consultant/)
* [Project Manager](https://regroove.ca/careers/project-manager-regroove/)

- [Cloud Solutions Consultant](https://regroove.ca/careers/cloud-solutions-consultant/)
- [Project Manager](https://regroove.ca/careers/project-manager-regroove/)

#### [Revela Systems](https://www.revela.io/)

Expand All @@ -163,8 +179,9 @@ Keep in mind that companies may have job postings on their own site that are not
#### [STN Video (formerly SendtoNews)](https://www.stnvideo.com/careers/)

#### [SilkStart](https://silkstart.com/about/)
* [Customer Success Specialist](https://www.silkstart.com/careers/)
* [Inside Sales](https://www.silkstart.com/careers/)

- [Customer Success Specialist](https://www.silkstart.com/careers/)
- [Inside Sales](https://www.silkstart.com/careers/)

#### [Starfish Medical](https://starfishmedical.com/) (πŸ‘©β€πŸ’» Co-Op / Intern Friendly)

Expand All @@ -177,6 +194,7 @@ Keep in mind that companies may have job postings on their own site that are not
#### [Vivid Solutions](https://www.vividsolutions.com/)

#### [Workday](https://www.workday.com/en-us/company/careers/open-positions.html#?q=&location=BC,%20Canada) (πŸ‘©β€πŸ’» Co-Op / Intern Friendly)

---

### Share this job board with others!
Expand Down
55 changes: 29 additions & 26 deletions link_checker/check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,26 +48,29 @@ find_links () {

for line in "${linkmap[@]}"; do
# For the lines in the mapfile,
# the keys are everything before a tab...
key="${line%$'\t*'}"
# ... and the values are everything after
value="${line##$'*\t'}"
# the keys and values are delimited by a tab.
IFS=$'\t' read -r key value <<< "$line"

# Assign to the associative array.
# This whole loop body could just have been
# LINKS["${line%$'\t*'}"]="${line##$'*\t'}",
# but that's a little cryptic, no?
LINKS[$key]=$value
done

[[ ! $QUIET ]] && echo >&2 "πŸ“Š Found ${#LINKS[@]} links in this document to test."
[[ $MARKDOWN ]] && echo "Checkboxes for links to remove: "
[[ $MARKDOWN ]] && echo -e "<!-- link-checker -->\n"

_queue_link_tests
exit_code=$?

[[ ! $QUIET ]] && echo >&2 "✨ Done checking! [${exit_code} problem(s)]"

if [[ $MARKDOWN ]]; then
if [[ $exit_code -eq 0 ]]; then
echo -e "\nLink checker tested ${#LINKS[@]} links and found none to be invalid!"
else
echo -e "\nLink checker tested ${#LINKS[@]} links and found the above broken links. Could you please remove them?"
fi
fi

exit "$exit_code"
}

Expand Down Expand Up @@ -104,7 +107,7 @@ test_link () {
return 0 # Skiping is OK, we warned

elif [[ ! "${scheme}" =~ $http_or_https || -z "${scheme}" ]]; then
[[ $MARKDOWN ]] && echo "* [ ] --- ${text} ${link} (Missing or unknown scheme)"
[[ $MARKDOWN ]] && echo "- ${text} ${link} (Missing or unknown scheme)"
[[ ! $QUIET ]] && echo >&2 "🦺 Skip: The scheme component on ${link} isn't http(s) or is empty."
return 1 # Missing scheme, www.example.com will be linked to a file in the repo

Expand All @@ -124,46 +127,46 @@ test_link () {
# 300 (Multiple Choice) is an example, so let's report on anything >= 300.
# Codes for reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
if [[ "$http_code" -ge 300 ]]; then
[[ $MARKDOWN ]] && echo "* [ ] ${http_code} ${text} ${link}"
[[ ! $QUIET ]] && echo >&2 "πŸ‘» [${http_code}] ${text} seems gone, from ${hostport}"
[[ $MARKDOWN ]] && echo -e "- ${text} (Page seems gone, status code ${http_code})\n > ${link}"
[[ ! $QUIET ]] && echo >&2 "πŸ‘» [${http_code}] REQUEST FAILED. ${link}"
return 1 # HTTP error, this is what this whole script for here for
fi

# See https://curl.haxx.se/libcurl/c/libcurl-errors.html for more cases we might
# want to handle.
if [[ "$curl_status" -eq 6 ]]; then
[[ $MARKDOWN ]] && echo "* [ ] --- ${text} ${link} (UNRESOLVED HOST)"
[[ ! $QUIET ]] && echo >&2 "🌎 [---] DNS lookup didn't resolve ${hostport}."
[[ $MARKDOWN ]] && echo -e "- ${text} (DNS lookup didn't resolve ${hostport}.)\n > ${link}"
[[ ! $QUIET ]] && echo >&2 "🌎 [---] UNRESOLVED HOST. ${link}"
return 1 # Failed DNS

elif [[ "$curl_status" -eq 7 ]]; then
[[ $MARKDOWN ]] && echo "* [ ] --- ${text} ${link} (COULDNT'T CONNECT TO SERVER)"
[[ ! $QUIET ]] && echo >&2 "πŸ“‘ [---] Couldn't connect to ${hostport}."
[[ $MARKDOWN ]] && echo -e "- ${text} (Couldn't connect to ${hostport})\n > ${link}"
[[ ! $QUIET ]] && echo >&2 "πŸ“‘ [---] COULDNT'T CONNECT TO SERVER. ${link}"
return 1 # Coudn't connect

elif [[ "$curl_status" -eq 28 ]]; then
[[ $MARKDOWN ]] && echo "* [ ] --- ${text} ${link} (TIMEOUT WAS REACHED)"
[[ ! $QUIET ]] && echo >&2 "βŒ› [---] Timed out with ${hostport}."
[[ $MARKDOWN ]] && echo -e "- ${text} (Timed out with ${hostport})\n > ${link}"
[[ ! $QUIET ]] && echo >&2 "βŒ› [---] TIMEOUT WAS REACHED. ${link}"
return 1 # Timed out

elif [[ "$curl_status" -eq 35 ]]; then
[[ $MARKDOWN ]] && echo "* [ ] --- ${text} ${link} (FAILED SSL HANDSHAKE)"
[[ ! $QUIET ]] && echo >&2 "🀝 [---] Handshaking with ${hostport} failed."
[[ $MARKDOWN ]] && echo -e "- ${text} (TLS handshaking with ${hostport} failed)\n > ${link}"
[[ ! $QUIET ]] && echo >&2 "🀝 [---] FAILED TLS HANDSHAKE. ${link}"
return 1 # Failed SSL

elif [[ "$curl_status" -eq 60 || "$curl_status" -eq 51 ]]; then
[[ $MARKDOWN ]] && echo "* [ ] --- ${text} ${link} (FAILED SSL VERIFICATION)"
[[ ! $QUIET ]] && echo >&2 "πŸ”“ [---] ${hostport}'s SSL certificate seems invalid!"
[[ $MARKDOWN ]] && echo -e "- ${text} (${hostport}'s TLS certificate seems invalid!)\n > ${link}"
[[ ! $QUIET ]] && echo >&2 "πŸ”“ [---] FAILED TLS VERIFICATION. ${link}"
return 1 # Failed SSL

elif [[ "$curl_status" -eq 130 ]]; then
[[ $MARKDOWN ]] && echo "* [ ] --- ${text} ${link} (SIGINT)"
[[ ! $QUIET ]] && echo >&2 "πŸ›‘ [---] Interrupted checking ${hostport}!"
[[ $MARKDOWN ]] && echo -e "- ${text} (Interrupted checking ${hostport}!)\n > ${link}"
[[ ! $QUIET ]] && echo >&2 "πŸ›‘ [---] SIGINT. ${link}"
return 1 # Interrupted

elif [[ ! "$curl_status" -eq 0 ]]; then
[[ $MARKDOWN ]] && echo "* [ ] --- ${text} ${link} (CURLcode: ${curl_status})"
[[ ! $QUIET ]] && echo >&2 "🀷 [---] Checking ${hostport} failed with CURLcode ${curl_status}"
[[ $MARKDOWN ]] && echo -e "- ${text} (Checking ${hostport} failed with CURLcode ${curl_status})\n > ${link}"
[[ ! $QUIET ]] && echo >&2 "🀷 [---] CURLcode: ${curl_status}. ${link}"
return 1 # cURL's unhappy, I'm unhappy
fi

Expand Down Expand Up @@ -286,7 +289,7 @@ _queue_link_tests () {
# Argument defaults
QUIET=
MARKDOWN=
WORKERS=4
WORKERS=10
INPUT_FILE=/dev/stdin

# Argument parsing
Expand Down

0 comments on commit 222f00b

Please sign in to comment.