Compare commits

..
2 changed files with 239 additions and 26 deletions
+193 -9
View File
@@ -16,8 +16,10 @@ jobs:
container: ghcr.io/xu-cheng/texlive-alpine:latest container: ghcr.io/xu-cheng/texlive-alpine:latest
steps: steps:
- name: Install system dependencies - name: Install system dependencies
run: apk add --no-cache git gettext bash nodejs poppler-utils run: apk add --no-cache git gettext bash nodejs
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Create public info file - name: Create public info file
env: env:
PERSONAL_NAME: ${{ secrets.PERSONAL_NAME || github.repository_owner }} PERSONAL_NAME: ${{ secrets.PERSONAL_NAME || github.repository_owner }}
@@ -26,6 +28,7 @@ jobs:
PERSONAL_SCHOOL_EMAIL: ${{ secrets.PERSONAL_SCHOOL_EMAIL || '' }} PERSONAL_SCHOOL_EMAIL: ${{ secrets.PERSONAL_SCHOOL_EMAIL || '' }}
run: | run: |
cat > personal_info.tex << 'EOL' cat > personal_info.tex << 'EOL'
% Public version of personal information
\newcommand{\personalName}{$PERSONAL_NAME} \newcommand{\personalName}{$PERSONAL_NAME}
\newcommand{\personalEmail}{$PERSONAL_EMAIL} \newcommand{\personalEmail}{$PERSONAL_EMAIL}
\newcommand{\personalPhone}{~} \newcommand{\personalPhone}{~}
@@ -39,16 +42,31 @@ jobs:
EOL EOL
envsubst < personal_info.tex > personal_info.tex.tmp envsubst < personal_info.tex > personal_info.tex.tmp
mv personal_info.tex.tmp personal_info.tex mv personal_info.tex.tmp personal_info.tex
- name: Cache TeX Live
uses: actions/cache@v4
with:
path: |
/tmp/texlive
~/.texlive*
key: texlive-${{ runner.os }}-${{ hashFiles('**/*.tex', 'subfiles/**/*.tex') }}
restore-keys: |
texlive-${{ runner.os }}-
- name: Create TeX Live directory
run: mkdir -p /tmp/texlive
- name: Compile LaTeX - name: Compile LaTeX
run: | run: |
latexmk -pdf -file-line-error -halt-on-error -interaction=nonstopmode resume.tex latexmk -pdf -file-line-error -halt-on-error -interaction=nonstopmode resume.tex
latexmk -pdf -file-line-error -halt-on-error -interaction=nonstopmode cv.tex latexmk -pdf -file-line-error -halt-on-error -interaction=nonstopmode cv.tex
- name: Enforce one-page resume
run: | - name: List generated PDFs
pages=$(pdfinfo resume.pdf | awk '/^Pages:/ {print $2}') run: ls -la *.pdf
echo "Resume pages: $pages"
test "$pages" -eq 1 # --- GITHUB RELEASES (Run only on GitHub) ---
- name: Update latest release - name: Upload Public PDFs as Release (GitHub)
if: github.server_url == 'https://github.com'
uses: ncipollo/release-action@v1 uses: ncipollo/release-action@v1
with: with:
artifacts: "resume.pdf,cv.pdf" artifacts: "resume.pdf,cv.pdf"
@@ -56,13 +74,15 @@ jobs:
name: Latest PDFs name: Latest PDFs
body: | body: |
Latest compiled resume and CV (public versions) Latest compiled resume and CV (public versions)
Built from commit ${{ github.sha }} Built from commit ${{ github.sha }}
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
allowUpdates: true allowUpdates: true
removeArtifacts: true removeArtifacts: true
replacesArtifacts: true replacesArtifacts: true
- name: Create numbered release
if: github.event_name == 'push' - name: Create Numbered Release (GitHub)
if: github.server_url == 'https://github.com'
uses: ncipollo/release-action@v1 uses: ncipollo/release-action@v1
with: with:
artifacts: "resume.pdf,cv.pdf" artifacts: "resume.pdf,cv.pdf"
@@ -70,7 +90,171 @@ jobs:
name: Release ${{ github.run_number }} name: Release ${{ github.run_number }}
body: | body: |
Automated release #${{ github.run_number }} Automated release #${{ github.run_number }}
Built from commit ${{ github.sha }} Built from commit ${{ github.sha }}
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
draft: false draft: false
prerelease: false prerelease: false
# --- GITEA RELEASES (Run only on Gitea) ---
- name: Upload Public PDFs as Release (Gitea)
if: github.server_url != 'https://github.com'
uses: akkuman/gitea-release-action@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
files: |
resume.pdf
cv.pdf
name: Latest PDFs
tag_name: latest
prerelease: false
draft: false
- name: Create Numbered Release (Gitea)
if: github.server_url != 'https://github.com'
uses: akkuman/gitea-release-action@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
files: |
resume.pdf
cv.pdf
name: Release ${{ github.run_number }}
tag_name: release-${{ github.run_number }}
prerelease: false
draft: false
build-private-github:
runs-on: ubuntu-latest
container: ghcr.io/xu-cheng/texlive-alpine:latest
if: github.actor == github.repository_owner && github.server_url == 'https://github.com'
steps:
- name: Install system dependencies
run: apk add --no-cache git gettext bash nodejs
- uses: actions/checkout@v4
- name: Create private info file
env:
PERSONAL_NAME: ${{ secrets.PERSONAL_NAME || github.repository_owner }}
PERSONAL_EMAIL: ${{ secrets.PERSONAL_EMAIL || '' }}
PERSONAL_WEBSITE: ${{ secrets.PERSONAL_WEBSITE || '' }}
PERSONAL_SCHOOL_EMAIL: ${{ secrets.PERSONAL_SCHOOL_EMAIL || '' }}
PERSONAL_PHONE: ${{ secrets.PERSONAL_PHONE || '' }}
PERSONAL_HOME_ADDRESS_LINE1: ${{ secrets.PERSONAL_HOME_ADDRESS_LINE1 || '' }}
PERSONAL_HOME_ADDRESS_LINE2: ${{ secrets.PERSONAL_HOME_ADDRESS_LINE2 || '' }}
PERSONAL_SCHOOL_ADDRESS_LINE1: ${{ secrets.PERSONAL_SCHOOL_ADDRESS_LINE1 || '' }}
PERSONAL_SCHOOL_ADDRESS_LINE2: ${{ secrets.PERSONAL_SCHOOL_ADDRESS_LINE2 || '' }}
PERSONAL_SCHOOL_ADDRESS_LINE3: ${{ secrets.PERSONAL_SCHOOL_ADDRESS_LINE3 || '' }}
run: |
cat > personal_info.tex << 'EOL'
% Private version of personal information
\newcommand{\personalName}{${PERSONAL_NAME}}
\newcommand{\personalEmail}{${PERSONAL_EMAIL}}
\newcommand{\personalPhone}{${PERSONAL_PHONE}}
\newcommand{\personalWebsite}{${PERSONAL_WEBSITE}}
\newcommand{\personalSchoolEmail}{${PERSONAL_SCHOOL_EMAIL}}
\newcommand{\personalHomeAddressLineOne}{${PERSONAL_HOME_ADDRESS_LINE1}}
\newcommand{\personalHomeAddressLineTwo}{${PERSONAL_HOME_ADDRESS_LINE2}}
\newcommand{\personalSchoolAddressLineOne}{${PERSONAL_SCHOOL_ADDRESS_LINE1}}
\newcommand{\personalSchoolAddressLineTwo}{${PERSONAL_SCHOOL_ADDRESS_LINE2}}
\newcommand{\personalSchoolAddressLineThree}{${PERSONAL_SCHOOL_ADDRESS_LINE3}}
EOL
envsubst < personal_info.tex > personal_info.tex.tmp
mv personal_info.tex.tmp personal_info.tex
- name: Cache TeX Live
uses: actions/cache@v4
with:
path: |
/tmp/texlive
~/.texlive*
key: texlive-${{ runner.os }}-${{ hashFiles('**/*.tex', 'subfiles/**/*.tex') }}
restore-keys: |
texlive-${{ runner.os }}-
- name: Create TeX Live directory
run: mkdir -p /tmp/texlive
- name: Compile LaTeX
run: |
latexmk -pdf -file-line-error -halt-on-error -interaction=nonstopmode resume.tex
latexmk -pdf -file-line-error -halt-on-error -interaction=nonstopmode cv.tex
- name: List generated PDFs
run: ls -la *.pdf
- name: Upload Private PDFs
uses: actions/upload-artifact@v4
with:
name: private-documents
path: |
resume.pdf
cv.pdf
build-private-gitea:
runs-on: ubuntu-latest
container: ghcr.io/xu-cheng/texlive-alpine:latest
if: github.actor == github.repository_owner && github.server_url != 'https://github.com'
steps:
- name: Install system dependencies
run: apk add --no-cache git gettext bash nodejs
- uses: actions/checkout@v4
- name: Create private info file
env:
PERSONAL_NAME: ${{ secrets.PERSONAL_NAME || github.repository_owner }}
PERSONAL_EMAIL: ${{ secrets.PERSONAL_EMAIL || '' }}
PERSONAL_WEBSITE: ${{ secrets.PERSONAL_WEBSITE || '' }}
PERSONAL_SCHOOL_EMAIL: ${{ secrets.PERSONAL_SCHOOL_EMAIL || '' }}
PERSONAL_PHONE: ${{ secrets.PERSONAL_PHONE || '' }}
PERSONAL_HOME_ADDRESS_LINE1: ${{ secrets.PERSONAL_HOME_ADDRESS_LINE1 || '' }}
PERSONAL_HOME_ADDRESS_LINE2: ${{ secrets.PERSONAL_HOME_ADDRESS_LINE2 || '' }}
PERSONAL_SCHOOL_ADDRESS_LINE1: ${{ secrets.PERSONAL_SCHOOL_ADDRESS_LINE1 || '' }}
PERSONAL_SCHOOL_ADDRESS_LINE2: ${{ secrets.PERSONAL_SCHOOL_ADDRESS_LINE2 || '' }}
PERSONAL_SCHOOL_ADDRESS_LINE3: ${{ secrets.PERSONAL_SCHOOL_ADDRESS_LINE3 || '' }}
run: |
cat > personal_info.tex << 'EOL'
% Private version of personal information
\newcommand{\personalName}{${PERSONAL_NAME}}
\newcommand{\personalEmail}{${PERSONAL_EMAIL}}
\newcommand{\personalPhone}{${PERSONAL_PHONE}}
\newcommand{\personalWebsite}{${PERSONAL_WEBSITE}}
\newcommand{\personalSchoolEmail}{${PERSONAL_SCHOOL_EMAIL}}
\newcommand{\personalHomeAddressLineOne}{${PERSONAL_HOME_ADDRESS_LINE1}}
\newcommand{\personalHomeAddressLineTwo}{${PERSONAL_HOME_ADDRESS_LINE2}}
\newcommand{\personalSchoolAddressLineOne}{${PERSONAL_SCHOOL_ADDRESS_LINE1}}
\newcommand{\personalSchoolAddressLineTwo}{${PERSONAL_SCHOOL_ADDRESS_LINE2}}
\newcommand{\personalSchoolAddressLineThree}{${PERSONAL_SCHOOL_ADDRESS_LINE3}}
EOL
envsubst < personal_info.tex > personal_info.tex.tmp
mv personal_info.tex.tmp personal_info.tex
- name: Cache TeX Live
uses: actions/cache@v4
with:
path: |
/tmp/texlive
~/.texlive*
key: texlive-${{ runner.os }}-${{ hashFiles('**/*.tex', 'subfiles/**/*.tex') }}
restore-keys: |
texlive-${{ runner.os }}-
- name: Create TeX Live directory
run: mkdir -p /tmp/texlive
- name: Compile LaTeX
run: |
latexmk -pdf -file-line-error -halt-on-error -interaction=nonstopmode resume.tex
latexmk -pdf -file-line-error -halt-on-error -interaction=nonstopmode cv.tex
- name: List generated PDFs
run: ls -la *.pdf
- name: Upload Private PDFs
uses: actions/upload-artifact@v3
with:
name: private-documents
path: |
resume.pdf
cv.pdf
+46 -17
View File
@@ -1,50 +1,79 @@
\documentclass{article} \documentclass{article}
% Include common style
\input{shared/style/common} \input{shared/style/common}
% Include personal information (check build/ first, then root)
\IfFileExists{build/personal_info.tex}{\input{build/personal_info}}{\input{personal_info}} \IfFileExists{build/personal_info.tex}{\input{build/personal_info}}{\input{personal_info}}
\begin{document} \begin{document}
% Header with contact information
\input{shared/sections/header} \input{shared/sections/header}
% Education section
\input{shared/sections/education} \input{shared/sections/education}
\resumesection{Publications \& Research} % Publications section
\textbf{Human-Robot Interaction Researcher, Bucknell University} \hfill \textbf{Jan 2023 May 2026} \resumesection{Publications}
\textbf{First Author, IEEE International Conference on Robot \& Human Interactive Communication (RO-MAN)}
\begin{itemize}[noitemsep,topsep=2pt] \begin{itemize}[noitemsep,topsep=2pt]
\item Published two first-author papers at IEEE RO-MAN (2024, 2025) on HRIStudio, a web-based Wizard-of-Oz platform for reproducible HRI studies; completed an honors thesis evaluating the platform \item O'Connor, S. \& Perrone, L.F. ``A Web-Based Wizard-of-Oz Platform for Collaborative and Reproducible HRI Research'' \textit{IEEE RO-MAN 2025}, Eindhoven, The Netherlands
\item Achieved 100\% design fidelity and 96.7\% execution reliability vs.\ 66.7\% baseline; SUS usability score 76.7 vs.\ 59.2 for Choregraphe \item O'Connor, S. \& Perrone, L.F. ``HRIStudio: A Framework for Wizard-of-Oz Experiments in HRI Studies'' \textit{IEEE RO-MAN 2024}, Pasadena, CA
\item Architected modular robot plugins, WebSocket teleoperation, comprehensive experiment logging, and RESTful ROS integration for NAO, Pepper, and custom robots \item O'Connor, S. ``A Web-Based Wizard-of-Oz Platform for Collaborative and Reproducible HRI Research'' \textit{Bachelor's Honors Thesis}, Bucknell University, 2026
\end{itemize}
\resumesection{Research Experience}
\textscbf{Bucknell University} \hfill \textscbf{Lewisburg, PA}
\textbf{Human-Robot Interaction Researcher} \hfill \textbf{Jan 2023 May 2026}
\begin{itemize}[noitemsep,topsep=2pt]
\item Published 2 first-author papers at IEEE RO-MAN (2024, 2025) on HRIStudio, a web-based Wizard-of-Oz platform enabling reproducible HRI studies across multiple robot platforms
\item Completed honors thesis evaluating HRIStudio via pilot study: achieved 100\% design fidelity and 96.7\% execution reliability vs.\ 66.7\% baseline; SUS score 76.7 vs.\ 59.2 for Choregraphe
\item Architected modular plugin system with WebSocket teleoperation, JSON-defined robot interfaces, comprehensive experiment logging, and RESTful ROS integration for NAO, Pepper, and custom robots
\end{itemize} \end{itemize}
\textit{O'Connor, S. \& Perrone, L.F.}, ``A Web-Based Wizard-of-Oz Platform for Collaborative and Reproducible HRI Research,'' IEEE RO-MAN 2025.\\
\textit{O'Connor, S. \& Perrone, L.F.}, ``HRIStudio: A Framework for Wizard-of-Oz Experiments in HRI Studies,'' IEEE RO-MAN 2024.
\resumesection{Professional Experience} \resumesection{Professional Experience}
\textscbf{Hadlock technologies LLC} \hfill \textscbf{New York} \textscbf{Hadlock technologies LLC} \hfill \textscbf{New York}
\textbf{Founder \& Software Engineer} \hfill \textbf{2026 Present} \textbf{Founder \& Software Engineer} \hfill \textbf{2026 Present}
\begin{itemize}[noitemsep,topsep=2pt] \begin{itemize}[noitemsep,topsep=2pt]
\item Founded Hadlock technologies LLC and built RaceTix, a digital ticketing platform integrating Shopify with signed, idempotent webhooks for automated ticket issuance and QR-code fulfillment \item Founded Hadlock technologies LLC and built RaceTix, a digital ticketing platform integrating Shopify with signed, idempotent webhooks for automated ticket issuance and QR-code fulfillment
\item Developed real-time scanning and redemption workflows with event validation, partial redemption, role-based permissions, and append-only audit logging \item Developed real-time staff scanning and redemption workflows supporting event-specific validation, partial ticket redemption, role-based permissions, and append-only audit logging
\end{itemize} \end{itemize}
\textscbf{Riverhead Raceway} \hfill \textscbf{Riverhead, NY} \textscbf{Riverhead Raceway} \hfill \textscbf{Riverhead, NY}
\textbf{Software Developer} \hfill \textbf{Oct 2020 Present} \textbf{Software Developer} \hfill \textbf{Oct 2020 Present}
\begin{itemize}[noitemsep,topsep=2pt] \begin{itemize}[noitemsep,topsep=2pt]
\item Architected and deployed RaceHub, a Next.js/TypeScript/PostgreSQL production platform serving 1,500+ concurrent users and 250k+ monthly visitors \item Architected and deployed RaceHub, a full-stack real-time statistics and content platform serving 1,500+ concurrent users and 250k+ monthly visitors using Next.js, TypeScript, PostgreSQL, and Docker
\item Designed APIs processing 10M+ requests monthly and built Docker/GitHub Actions CI/CD, monitoring, and automated operations maintaining 99.9\% uptime during racing season \item Designed production APIs for mobile applications and third-party integrations, processing 10M+ requests monthly while supporting payment and operational workflows
\item Built CI/CD pipelines with GitHub Actions, containerized deployments, monitoring, and automated operations maintaining 99.9\% uptime during racing season
\end{itemize} \end{itemize}
\textscbf{Bucknell University} \hfill \textscbf{Lewisburg, PA} \textscbf{Bucknell University} \hfill \textscbf{Lewisburg, PA}
\textbf{Teaching Assistant Software Engineering \& Engineering Design} \hfill \textbf{Aug 2023 May 2026} \textbf{Teaching Assistant Software Engineering \& Engineering Design} \hfill \textbf{Aug 2023 May 2026}
\begin{itemize}[noitemsep,topsep=2pt] \begin{itemize}[noitemsep,topsep=2pt]
\item Mentored 150+ students in software engineering, design patterns, and embedded systems; developed automated testing and grading tools \item Mentored 150+ students across software engineering, design patterns, and embedded systems; developed automated testing and grading tools used in coursework
\end{itemize} \end{itemize}
\resumesection{Selected Engineering Projects} \resumesection{Selected Projects}
\textbf{Computer System from Scratch Nand2Tetris} \hfill \textbf{HDL/Assembly/Java} \textbf{Computer System from Scratch Nand2Tetris} \hfill \textbf{HDL/Assembly/Java}
\begin{itemize}[noitemsep,topsep=2pt] \begin{itemize}[noitemsep,topsep=2pt]
\item Built a complete computer from NAND gates through OS: designed ALU, CPU, and memory and implemented an assembler, VM translator, compiler, and operating system \item Built a complete computer from NAND gates through operating system: designed ALU, CPU, and memory components and implemented an assembler, VM translator, compiler, and OS
\end{itemize}
\textbf{Autonomous Vehicle Control Chem-E-Car} \hfill \textbf{C++/Arduino}
\begin{itemize}[noitemsep,topsep=2pt]
\item Led a 15-member interdisciplinary team; implemented finite-state embedded control and real-time sensor integration achieving \textpm10cm distance precision in AIChE competition
\end{itemize} \end{itemize}
\textbf{Autonomous Vehicle Control Chem-E-Car Competition} \hfill \textbf{C++/Arduino}
\begin{itemize}[noitemsep,topsep=2pt]
\item Led 15-member interdisciplinary team; implemented finite-state embedded control and real-time sensor integration achieving \textpm10cm distance precision in AIChE competition
\end{itemize}
% Technical Skills
\input{shared/sections/skills-resume} \input{shared/sections/skills-resume}
\end{document} \end{document}