Software Engineering II: Projects & CI/CD
Philipp Fruck Project structure ██ Example samplerepo/
├── .git/ # git project folder
├── container/ # container files
├── docs/ # documentation (user, dev, admin)
├── scripts/ # utilities used for development
├── src/ # source folder (depends on language)
├── .prettierrc # config file for tooling
├── CODEOWNERS # define team responsibilities
├── Justfile # (or Makefile) script runner
├── README.md # project overview
└── LICENSE # open source license,
# otherwise proprietary
▓▓▓ How do I choose a license? • Choose a license (https://choosealicense.com)
• Tabular Overview (https://choosealicense.com/appendix)
• Interactive wizard (https://choosingalicense.com/wizard)
• TLDR Legal (https://tldrlegal.com)
Software Engineering II: Projects & CI/CD 2 / 15
Mono vs Multi-Repo ██ Mono-Repo ██ Multi-Repo
All components in a single repository One repo per component
▓▓▓ Pros: ▓▓▓ Pros:
• Unified Versioning • Separation of Concerns
• Cross-Project Changes • Independent Versioning
• Consistency • Smaller Codebases
• Shared Resources • Granular Access Control
• Simplified CI/CD ▓▓▓ Cons: ▓▓▓ Cons:
• Scalability Issues • Dependency Management
• Complexity • Cross-Repo Changes
• Longer Checkout/Clone Times • Integration Overhead
• Access Control • Tooling Complexity
Software Engineering II: Projects & CI/CD 3 / 15
What is CI/CD? ██ Description![]()
CI/CD is a set of practices to automate software development processes, ensuring that code changes are continuously integrated and deployed. 1. Continuous Integration (CI):
◦ Automating the frequent integration code into a shared repository ◦ Formatting, linting, typechecking ◦ Build & test 2. Continuous Delivery (CD):
◦ Automatically deploy to testing/staging after CI is passed 3. Continuous Deployment (also CD):
◦ Automatically deploy to production Software Engineering II: Projects & CI/CD 4 / 15
Why is CI/CD Useful? CI/CD brings significant benefits to software development teams: • Faster feedback loops ◦ Immediate testing and validation of code ◦ No broken code gets merged • Better code quality ◦ Automated testing ensures code works as expected ◦ Codebase is always in usable state • Reduced manual work ◦ Automation handles repetitive tasks like deployment • Enhanced collaboration ◦ CI/CD reduces integration issues (wrong styling, bugs, ...) • Reproducability ◦ No "it works on my machine" ◦ No handcrafted deployments/manual patches Software Engineering II: Projects & CI/CD 5 / 15
How Does CI/CD Work? CI/CD works through the use of pipelines:
1. Developers push code to a version control system (e.g., GitHub/GitLab/Codeberg). 2. A CI pipeline automatically builds and tests the code.
3. If the tests pass, the code is automatically deployed through a CD pipeline.
This process ensures that code is always in a deployable state. Software Engineering II: Projects & CI/CD 6 / 15
CI/CD Examples We take a look at some simple actions for GitHub, Forgejo (Codeberg) and GitLab. All three action types share the following ideas: • Actions have different entrypoints ◦ Run after git push to certain branch ◦ Run for merge requests ◦ Schedules execution, e.g. weekly run • Run on different operating systems or containers ◦ E.g. build application on Windows, MacOS and Linux • Divide into different stages (lint/build/test/deploy) • Reuse existing snippets (actions/components) • Create/share artifacts ◦ E.g. compiled executable or website ◦ Upload release binary or deploy to webserver Software Engineering II: Projects & CI/CD 7 / 15
GitHub Actions: CI/CD Example GitHub Actions uses workflows defined in .github/workflows/
name: CI/CD Pipeline
• Each workflow can have multiple jobs on:
• A job is a set of steps push:
◦ Steps are executed sequentally (same runner) branches: [main]
◦ Data sharing possible jobs:
• By default all jobs run in parallel build:
◦ Dependencies between jobs can be configured runs-on: ubuntu-latest
• Actions are reusable sets of jobs or code steps:
◦ Can be used to checkout code/install tools etc. - uses: actions/checkout@v6
- name: Set up Node.js
Full syntax ( uses: actions/setup-node@v6
https://docs.github.com/en/actions/reference/workflows-and-actions/work with:
flow-syntax) node-version: '24'
- name: Install Dependencies
run: npm ci
- name: Run Tests
run: npm test
Software Engineering II: Projects & CI/CD 8 / 15
GitLab CI/CD Example GitLab uses the term pipelines for CI/CD. Pipelines are defined in the
.gitlab-ci.yml include:
- component:
• Reusable components can be used via include $CI_SERVER_FQDN/my-org/security-components/
• Jobs are defined at top-level secret-detection@1.0
• Jobs are divided into stages stages:
◦ Stages are executed sequentially - build
◦ Jobs in a single stage run in parallel - test
• Rules are used to conditionally run a job build-job:
• default can be used to apply config to all jobs stage: build
image: node
Full syntax (https://docs.gitlab.com/ci/yaml/) script:
- npm ci
test-job:
stage: test
script:
- npm run test
rules:
# e.g. only run on main
- if: $CI_COMMIT_BRANCH ==
$CI_DEFAULT_BRANCH
Software Engineering II: Projects & CI/CD 9 / 15
Forgejo CI/CD Example Forgejo (Gitea fork) supports CI/CD through Forgejo Actions
name: Forgejo CI Pipeline
• Very similar to GitHub Actions on:
• Actions can be specified using relative or full URL push:
◦ set DEFAULT_ACTIONS_URL as an admin branches:
◦ Use full HTTPS URL for custom actions - main
• For simple pipelines Forgejo and GitHub Actions should be jobs:
identical build:
◦ But there exist subtle differences ( runs-on: ubuntu-latest
https://forgejo.org/docs/latest/user/actions/github-actions/) steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: '24'
- name: Install dependencies
run: npm install
- name: Run tests
run: npm test
Software Engineering II: Projects & CI/CD 10 / 15
Saving Pipeline Data Artifacts can be used to save pipelines data (and share it between jobs)
██ GitHub / Forgejo ██ GitLab
jobs: stages: [build, consume]
build: build:
steps: stage: build
- run: echo "Hello world" > message.txt script:
- name: Upload artifact - echo "Hello world" > message.txt
uses: actions/upload-artifact@v4 artifacts:
with: paths:
name: my-artifact - message.txt
path: message.txt consume:
consume: stage: consume
steps: needs:
- name: Download artifact - job: build
uses: actions/download-artifact@v4 artifacts: true
with: script:
name: my-artifact - cat message.txt
- run: cat message.txt
Software Engineering II: Projects & CI/CD 11 / 15
Matrix Execution Sometimes we want to parameterize our pipelines: • Build for multiple CPU architectures • Test against multiple runtime versions This can be achieved using a matrix
██ GitHub / Forgejo ██ GitLab
jobs: test:
test: image: node:$NODE_VERSION
runs-on: ubuntu-latest parallel:
strategy: matrix:
matrix: - NODE_VERSION: [22, 24, 25]
node: [22, 24, 25]
steps: script:
- uses: actions/checkout@v4 - npm ci
- name: Setup Node - npm test
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm ci
- run: npm test
Software Engineering II: Projects & CI/CD 12 / 15
CI/CD Best Practices 1. Automate testing: Ensure every change is tested automatically.
2. Keep pipelines fast: Avoid long-running tests to maintain fast feedback.
3. Deploy often: Deploy to production regularly for quicker user feedback.
4. Monitor pipelines: Keep track of pipeline performance and failures.
Software Engineering II: Projects & CI/CD 13 / 15
Exercise Now you have time to run some pipelines yourself! • Create pipelines to setup, build and test your project • Consider adding pipelines for tooling (formatting/linting) as well • If you still have time, try using artifacts and matrices Software Engineering II: Projects & CI/CD 14 / 15
Thank you for your attention! Don't forget the feedback Software Engineering II: Projects & CI/CD 15 / 15