From e5158ed234f6a1ef6f94e32a2e0685793db5c6b5 Mon Sep 17 00:00:00 2001 From: MorVered7 Date: Mon, 17 Feb 2025 11:15:03 -0800 Subject: [PATCH 01/17] added lessons --- .../topic-1-git/chapter-5-advanced-git-techniques/index.md | 0 .../topic-3-devsecops/chapter-3-security-frameworks/index.md | 0 docs/course/topic-3-devsecops/chapter-4-cloud-security/index.md | 0 .../chapter-5-threat-modeling-and-risk-assessment/index.md | 0 .../chapter-6-secure-code-and-hardening/index.md | 0 .../labs/sql-injection-lab.md | 0 .../topic-3-devsecops/chapter-7-supply-chain-security/index.md | 0 .../labs/detecting-vulnerabilities-lab.md | 1 + 8 files changed, 1 insertion(+) create mode 100644 docs/course/topic-1-git/chapter-5-advanced-git-techniques/index.md create mode 100644 docs/course/topic-3-devsecops/chapter-3-security-frameworks/index.md create mode 100644 docs/course/topic-3-devsecops/chapter-4-cloud-security/index.md create mode 100644 docs/course/topic-3-devsecops/chapter-5-threat-modeling-and-risk-assessment/index.md create mode 100644 docs/course/topic-3-devsecops/chapter-6-secure-code-and-hardening/index.md create mode 100644 docs/course/topic-3-devsecops/chapter-6-secure-code-and-hardening/labs/sql-injection-lab.md create mode 100644 docs/course/topic-3-devsecops/chapter-7-supply-chain-security/index.md create mode 100644 docs/course/topic-3-devsecops/chapter-7-supply-chain-security/labs/detecting-vulnerabilities-lab.md diff --git a/docs/course/topic-1-git/chapter-5-advanced-git-techniques/index.md b/docs/course/topic-1-git/chapter-5-advanced-git-techniques/index.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/course/topic-3-devsecops/chapter-3-security-frameworks/index.md b/docs/course/topic-3-devsecops/chapter-3-security-frameworks/index.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/course/topic-3-devsecops/chapter-4-cloud-security/index.md b/docs/course/topic-3-devsecops/chapter-4-cloud-security/index.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/course/topic-3-devsecops/chapter-5-threat-modeling-and-risk-assessment/index.md b/docs/course/topic-3-devsecops/chapter-5-threat-modeling-and-risk-assessment/index.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/course/topic-3-devsecops/chapter-6-secure-code-and-hardening/index.md b/docs/course/topic-3-devsecops/chapter-6-secure-code-and-hardening/index.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/course/topic-3-devsecops/chapter-6-secure-code-and-hardening/labs/sql-injection-lab.md b/docs/course/topic-3-devsecops/chapter-6-secure-code-and-hardening/labs/sql-injection-lab.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/course/topic-3-devsecops/chapter-7-supply-chain-security/index.md b/docs/course/topic-3-devsecops/chapter-7-supply-chain-security/index.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/course/topic-3-devsecops/chapter-7-supply-chain-security/labs/detecting-vulnerabilities-lab.md b/docs/course/topic-3-devsecops/chapter-7-supply-chain-security/labs/detecting-vulnerabilities-lab.md new file mode 100644 index 0000000..66aef38 --- /dev/null +++ b/docs/course/topic-3-devsecops/chapter-7-supply-chain-security/labs/detecting-vulnerabilities-lab.md @@ -0,0 +1 @@ +detecting vulnerabilities in open source dependencies \ No newline at end of file From 1ec789c25248a1f46feee7e8a2eb9d780c0e788a Mon Sep 17 00:00:00 2001 From: MorVered7 Date: Mon, 17 Feb 2025 11:17:56 -0800 Subject: [PATCH 02/17] added some labs --- .../labs/securing-a-vulnerable-web-app.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/course/topic-3-devsecops/chapter-6-secure-code-and-hardening/labs/securing-a-vulnerable-web-app.md diff --git a/docs/course/topic-3-devsecops/chapter-6-secure-code-and-hardening/labs/securing-a-vulnerable-web-app.md b/docs/course/topic-3-devsecops/chapter-6-secure-code-and-hardening/labs/securing-a-vulnerable-web-app.md new file mode 100644 index 0000000..e69de29 From 62d1914125dc88abea4e3f4d53cb60d783613cfe Mon Sep 17 00:00:00 2001 From: jsmargarones Date: Fri, 18 Apr 2025 15:26:47 -0700 Subject: [PATCH 03/17] Changes to structure of topics and chapters --- .../chapter-1-SDLC/index.md | 11 ++ .../chapter-2-version-control/index.md | 38 ++++++ .../chapter-3-intro-to-devOps}/index.md | 6 +- .../chapter-4-intro-to-cicd/index.md | 124 ++++++++++++++++++ .../chapter-5-intro-to-devsecops/index.md | 104 +++++++++++++++ .../index.md | 18 +++ .../review-and-knowledge-check/index.md | 9 ++ .../chapter-1-version-control/index.md | 4 +- .../chapter-2-understanding-git/Git.jpg | Bin .../chapter-2-understanding-git/index.md | 2 +- .../lab/csd-lab-1.md | 0 .../chapter-3-Intermediate-Concepts/index.md | 2 +- .../lab/git-lab-1.md | 2 +- .../chapter-4-git-best-practices/index.md | 2 +- .../index.md | 9 ++ .../{topic-1-git => Topic-2-Git}/index.md | 6 +- .../review-and-knowledge-check/index.md | 9 ++ .../chapter-1-cicd-core-concepts}/index.md | 6 +- .../chapter-2-webhooks}/index.md | 6 +- .../chapter-3-automated-testing}/index.md | 6 +- .../chapter-4-deployment}/index.md | 6 +- .../lab/deployment-lab-1.md | 4 +- .../lab/imgs/jenkins-login.png | Bin .../lab/imgs/wireguard.png | Bin .../chapter-4-deployment}/lab/overview.md | 4 +- .../chapter-5-containerization}/index.md | 6 +- .../lab/containerization-lab-1.md | 4 +- .../lab/containerization-lab-2.md | 4 +- .../lab/imgs/clone.png | Bin .../lab/imgs/dashboard.png | Bin .../lab/imgs/fork.png | Bin .../lab/imgs/wireguard.png | Bin .../lab/overview.md | 4 +- docs/course/Topic-3-CICD-Concepts/index.md | 13 ++ .../review-and-knowledge-check/index.md | 9 ++ .../chapter-1-devsecops/index.md | 2 +- .../labs/devsecops-lab-1.md | 0 .../index.md | 2 +- .../lab/devsecops-lab-1.md | 0 .../lab/overview.md | 0 .../index.md | 4 +- docs/course/Topic-5-Cloud/index.md | 15 +++ .../index.md | 0 docs/course/topic-2-DevOps/index.md | 19 --- .../chapter-3-security-frameworks/index.md | 0 .../chapter-4-cloud-security/index.md | 0 .../index.md | 0 .../index.md | 0 .../labs/securing-a-vulnerable-web-app.md | 0 .../labs/sql-injection-lab.md | 0 .../chapter-7-supply-chain-security/index.md | 0 .../labs/detecting-vulnerabilities-lab.md | 1 - docs/other/index.md | 2 +- index.md | 10 -- 54 files changed, 401 insertions(+), 72 deletions(-) create mode 100644 docs/course/Topic-1-Software-Dev-and-DevSecOps/chapter-1-SDLC/index.md create mode 100644 docs/course/Topic-1-Software-Dev-and-DevSecOps/chapter-2-version-control/index.md rename docs/course/{topic-2-DevOps/chapter-1-intro-to-devops => Topic-1-Software-Dev-and-DevSecOps/chapter-3-intro-to-devOps}/index.md (99%) create mode 100644 docs/course/Topic-1-Software-Dev-and-DevSecOps/chapter-4-intro-to-cicd/index.md create mode 100644 docs/course/Topic-1-Software-Dev-and-DevSecOps/chapter-5-intro-to-devsecops/index.md create mode 100644 docs/course/Topic-1-Software-Dev-and-DevSecOps/index.md create mode 100644 docs/course/Topic-1-Software-Dev-and-DevSecOps/review-and-knowledge-check/index.md rename docs/course/{topic-1-git => Topic-2-Git}/chapter-1-version-control/index.md (97%) rename docs/course/{topic-1-git => Topic-2-Git}/chapter-2-understanding-git/Git.jpg (100%) rename docs/course/{topic-1-git => Topic-2-Git}/chapter-2-understanding-git/index.md (99%) rename docs/course/{topic-1-git => Topic-2-Git}/chapter-2-understanding-git/lab/csd-lab-1.md (100%) rename docs/course/{topic-1-git => Topic-2-Git}/chapter-3-Intermediate-Concepts/index.md (99%) rename docs/course/{topic-1-git => Topic-2-Git}/chapter-3-Intermediate-Concepts/lab/git-lab-1.md (98%) rename docs/course/{topic-1-git => Topic-2-Git}/chapter-4-git-best-practices/index.md (99%) create mode 100644 docs/course/Topic-2-Git/chapter-5-advanced-git-techniques/index.md rename docs/course/{topic-1-git => Topic-2-Git}/index.md (95%) create mode 100644 docs/course/Topic-2-Git/review-and-knowledge-check/index.md rename docs/course/{topic-2-DevOps/chapter-2-intro-to-ci-cd => Topic-3-CICD-Concepts/chapter-1-cicd-core-concepts}/index.md (98%) rename docs/course/{topic-2-DevOps/chapter-4-webhooks => Topic-3-CICD-Concepts/chapter-2-webhooks}/index.md (97%) rename docs/course/{topic-2-DevOps/chapter-5-automation => Topic-3-CICD-Concepts/chapter-3-automated-testing}/index.md (98%) rename docs/course/{topic-2-DevOps/chapter-6-deployment => Topic-3-CICD-Concepts/chapter-4-deployment}/index.md (99%) rename docs/course/{topic-2-DevOps/chapter-6-deployment => Topic-3-CICD-Concepts/chapter-4-deployment}/lab/deployment-lab-1.md (99%) rename docs/course/{topic-2-DevOps/chapter-6-deployment => Topic-3-CICD-Concepts/chapter-4-deployment}/lab/imgs/jenkins-login.png (100%) rename docs/course/{topic-2-DevOps/chapter-3-containerization => Topic-3-CICD-Concepts/chapter-4-deployment}/lab/imgs/wireguard.png (100%) rename docs/course/{topic-2-DevOps/chapter-6-deployment => Topic-3-CICD-Concepts/chapter-4-deployment}/lab/overview.md (96%) rename docs/course/{topic-2-DevOps/chapter-3-containerization => Topic-3-CICD-Concepts/chapter-5-containerization}/index.md (99%) rename docs/course/{topic-2-DevOps/chapter-3-containerization => Topic-3-CICD-Concepts/chapter-5-containerization}/lab/containerization-lab-1.md (99%) rename docs/course/{topic-2-DevOps/chapter-3-containerization => Topic-3-CICD-Concepts/chapter-5-containerization}/lab/containerization-lab-2.md (98%) rename docs/course/{topic-2-DevOps/chapter-3-containerization => Topic-3-CICD-Concepts/chapter-5-containerization}/lab/imgs/clone.png (100%) rename docs/course/{topic-2-DevOps/chapter-3-containerization => Topic-3-CICD-Concepts/chapter-5-containerization}/lab/imgs/dashboard.png (100%) rename docs/course/{topic-2-DevOps/chapter-3-containerization => Topic-3-CICD-Concepts/chapter-5-containerization}/lab/imgs/fork.png (100%) rename docs/course/{topic-2-DevOps/chapter-6-deployment => Topic-3-CICD-Concepts/chapter-5-containerization}/lab/imgs/wireguard.png (100%) rename docs/course/{topic-2-DevOps/chapter-3-containerization => Topic-3-CICD-Concepts/chapter-5-containerization}/lab/overview.md (96%) create mode 100644 docs/course/Topic-3-CICD-Concepts/index.md create mode 100644 docs/course/Topic-3-CICD-Concepts/review-and-knowledge-check/index.md rename docs/course/{topic-3-devsecops => Topic-4-Devsecops-Fundmentals}/chapter-1-devsecops/index.md (99%) rename docs/course/{topic-3-devsecops => Topic-4-Devsecops-Fundmentals}/chapter-1-devsecops/labs/devsecops-lab-1.md (100%) rename docs/course/{topic-3-devsecops => Topic-4-Devsecops-Fundmentals}/chapter-2-security-checks-in-CICD/index.md (99%) rename docs/course/{topic-3-devsecops => Topic-4-Devsecops-Fundmentals}/chapter-2-security-checks-in-CICD/lab/devsecops-lab-1.md (100%) rename docs/course/{topic-3-devsecops => Topic-4-Devsecops-Fundmentals}/chapter-2-security-checks-in-CICD/lab/overview.md (100%) rename docs/course/{topic-3-devsecops => Topic-4-Devsecops-Fundmentals}/index.md (90%) create mode 100644 docs/course/Topic-5-Cloud/index.md delete mode 100644 docs/course/topic-1-git/chapter-5-advanced-git-techniques/index.md delete mode 100644 docs/course/topic-2-DevOps/index.md delete mode 100644 docs/course/topic-3-devsecops/chapter-3-security-frameworks/index.md delete mode 100644 docs/course/topic-3-devsecops/chapter-4-cloud-security/index.md delete mode 100644 docs/course/topic-3-devsecops/chapter-5-threat-modeling-and-risk-assessment/index.md delete mode 100644 docs/course/topic-3-devsecops/chapter-6-secure-code-and-hardening/index.md delete mode 100644 docs/course/topic-3-devsecops/chapter-6-secure-code-and-hardening/labs/securing-a-vulnerable-web-app.md delete mode 100644 docs/course/topic-3-devsecops/chapter-6-secure-code-and-hardening/labs/sql-injection-lab.md delete mode 100644 docs/course/topic-3-devsecops/chapter-7-supply-chain-security/index.md delete mode 100644 docs/course/topic-3-devsecops/chapter-7-supply-chain-security/labs/detecting-vulnerabilities-lab.md diff --git a/docs/course/Topic-1-Software-Dev-and-DevSecOps/chapter-1-SDLC/index.md b/docs/course/Topic-1-Software-Dev-and-DevSecOps/chapter-1-SDLC/index.md new file mode 100644 index 0000000..0676e56 --- /dev/null +++ b/docs/course/Topic-1-Software-Dev-and-DevSecOps/chapter-1-SDLC/index.md @@ -0,0 +1,11 @@ +--- +title: Chapter 1 - Introduction to SDLC +layout: custom +parent: Topic 1 - Introduction to SDLC and DevSecOps +has_children: false +has_toc: false +nav_order: 1 +--- + +# Chapter 1 - Introduction to SDLC +## What is the Software Development Lifecycle (SDLC)? diff --git a/docs/course/Topic-1-Software-Dev-and-DevSecOps/chapter-2-version-control/index.md b/docs/course/Topic-1-Software-Dev-and-DevSecOps/chapter-2-version-control/index.md new file mode 100644 index 0000000..0f72ec8 --- /dev/null +++ b/docs/course/Topic-1-Software-Dev-and-DevSecOps/chapter-2-version-control/index.md @@ -0,0 +1,38 @@ +--- +title: Chapter 2 - Version Control +layout: custom +parent: Topic 1 - Introduction to SDLC and DevSecOps +has_children: false +has_toc: false +nav_order: 2 +--- + +# Chapter 1 - Introduction to Version Control +## What is version control? +Version control is **a system that records changes to a file or set of files over time** so that you can recall specific versions later. It's a critical tool in modern software development, allowing developers to work collaboratively, track every modification, and revert to previous states if necessary. + +> **Example Scenario** +> +> Armine and Tigran are part of a software development team tasked with creating a new mobile application. Armine is tasked with refining the user authentication system, while Tigran is implementing an innovative feature that allows users to share media within the app. +> +> **Without Version Control**: If Armine and Tigran are editing the same file, Tigran's latest upload could accidentally overwrite the changes Armine made, resulting in a loss of progress and potential conflicts in the code. +> +> **With Version Control**: Armine and Tigran can work on their updates concurrently without the risk of interfering with each other's contributions. Here's how it unfolds: +> +> - Independently, they make their changes and commit their updates to the version control system, each creating a new version in the repository. +> +> - The version control system alerts them to the presence of new, separate updates, signaling that a merge of changes is necessary. +> +> - Together, they examine the differences, carefully integrate their respective code changes, and commit the unified version to the repository. +> +> - Should an issue arise with the authentication update, Armine can revert her portion of the code to a previous state without disrupting Tigran's feature, thanks to the version history maintained by the system. + +A common tool for version control is GitHub. GitHub allows you acts as a central hub for all of the different versions of your code, kind of how in google docs you can see the history of your changes. Though there are many different systems for version control, we will be learning using GitHubs features. The syntax and user interface of different products are different, but the core elements are the same. + +### References +
+ Expand + 1. Atlassian. “What Is Version Control: Atlassian Git Tutorial.” Atlassian, www.atlassian.com/git/tutorials/what-is-version-control. Accessed 15 Apr. 2024.
+ 2. “1.1 Getting Started - about Version Control.” Git, git-scm.com/book/en/v2/Getting-Started-About-Version-Control. Accessed 15 Apr. 2024.
+ 3. “What Is Version Control?” GitLab, GitLab, 4 Apr. 2023, about.gitlab.com/topics/version-control/.
+
\ No newline at end of file diff --git a/docs/course/topic-2-DevOps/chapter-1-intro-to-devops/index.md b/docs/course/Topic-1-Software-Dev-and-DevSecOps/chapter-3-intro-to-devOps/index.md similarity index 99% rename from docs/course/topic-2-DevOps/chapter-1-intro-to-devops/index.md rename to docs/course/Topic-1-Software-Dev-and-DevSecOps/chapter-3-intro-to-devOps/index.md index 2632916..32c0965 100644 --- a/docs/course/topic-2-DevOps/chapter-1-intro-to-devops/index.md +++ b/docs/course/Topic-1-Software-Dev-and-DevSecOps/chapter-3-intro-to-devOps/index.md @@ -1,10 +1,10 @@ --- -title: Chapter 1 - Intro to DevOps +title: Chapter 3 - Intro to DevOps layout: custom -parent: Topic 2 - DevOps +parent: Topic 1 - Introduction to SDLC and DevSecOps has_children: false has_toc: false -nav_order: 1 +nav_order: 3 --- # Introduction to DevOps ## Problem Space diff --git a/docs/course/Topic-1-Software-Dev-and-DevSecOps/chapter-4-intro-to-cicd/index.md b/docs/course/Topic-1-Software-Dev-and-DevSecOps/chapter-4-intro-to-cicd/index.md new file mode 100644 index 0000000..8dd0a2d --- /dev/null +++ b/docs/course/Topic-1-Software-Dev-and-DevSecOps/chapter-4-intro-to-cicd/index.md @@ -0,0 +1,124 @@ +--- +title: Chapter 4 - Intro to CI/CD +layout: custom +parent: Topic 1 - Introduction to SDLC and DevSecOps +has_children: false +has_toc: false +nav_order: 4 +--- + +# Introduction to CI/CD +

CI/CD, short for Continuous Integration and Continuous Delivery, is a part of the DevOps process. “It is a collection of principles and practices designed to help development teams ensure the reliable delivery of frequent code changes.”

+ +
+ CI/CD Lifecycle +

Source: Mind The Product

+ +
+ +## DevOps vs. CI/CD + + + + + + + + + + + + + + + + + + + + + + + + + + +
CategoryDevOpsCICD
PurposeFacilitate collaboration and efficiency across the development lifecycle.Automate testing to ensure code compatibility.Automate deployment for seamless software releases.
Methods +
    +
  • Implement automation to streamline collaboration between development and operations teams.
  • +
  • Use infrastructure as code (IaC) to provision and manage infrastructure.
  • +
  • Integrate continuous feedback loops to gather insights from stakeholders and improve processes iteratively.
  • +
+
+
    +
  • Automate the build and testing process for every code change.
  • +
  • Identify integration issues early in the development lifecycle.
  • +
  • Support the principle of "fail fast" by providing rapid feedback to developers.
  • +
+
+
    +
  • Encompass both Continuous Integration and Continuous Deployment.
  • +
  • Automate the deployment process to production environments.
  • +
  • Enable organizations to release software updates quickly and reliably while minimizing risks.
  • +
+
Key Benefits +
    +
  • Promotes a culture of shared responsibility and accountability.
  • +
  • Emphasizes the importance of automating repetitive tasks to reduce manual errors and increase efficiency.
  • +
  • Focuses on delivering value to customers through rapid and iterative development cycles.
  • +
+
+
    +
  • Increases code quality by identifying issues early in the development process.
  • +
  • Speeds up the development cycle by automating build and testing processes.
  • +
  • Enables rapid feedback to developers for quick iterations.
  • +
+
+
    +
  • Accelerates time to market by automating deployment processes.
  • +
  • Minimizes risks associated with manual deployments.
  • +
  • Enhances overall software reliability and stability.
  • +
+
+ +### References +
+ Expand + 1. Ashtari, Hossein et al. “Key Differences between CI/CD and DevOps.” Spiceworks, www.spiceworks.com/tech/devops/articles/cicd-vs-devops/. Accessed 20 Feb. 2024.
+ 2. Ferringer, Megan. “Here’s the Difference between CI/CD and Devops-and How They Work Together to Drive Innovation.” Navisite, 2 Mar. 2023, www.navisite.com/blog/insights/ci-cd-vs-devops/.
+ 3. “What the Hell Are CI/CD and DevOps? A Cheatsheet for the Rest of Us.” Mind the Product, www.mindtheproduct.com/what-the-hell-are-ci-cd-and-devops-a-cheatsheet-for-the-rest-of-us/. Accessed 20 Feb. 2024.
+ 4. “The IDEAL & Practical CI / CD Pipeline - Concepts Overview.” YouTube, 17 Feb. 2022, www.youtube.com/watch?v=OPwU3UWCxhw.
+ 5. Morg, Brad. “How to Design a Modern CI/CD Pipeline.” YouTube, 17 Oct. 2023, www.youtube.com/watch?v=KnSBNd3b0qI.
+ 6. Morg, Brad. “How to Design a Deployment Pipeline (GitOps).” YouTube, 30 Oct. 2023, www.youtube.com/watch?v=pJ9f7w4AxtU.
+
diff --git a/docs/course/Topic-1-Software-Dev-and-DevSecOps/chapter-5-intro-to-devsecops/index.md b/docs/course/Topic-1-Software-Dev-and-DevSecOps/chapter-5-intro-to-devsecops/index.md new file mode 100644 index 0000000..7d641f7 --- /dev/null +++ b/docs/course/Topic-1-Software-Dev-and-DevSecOps/chapter-5-intro-to-devsecops/index.md @@ -0,0 +1,104 @@ +--- +title: Chapter 5 - Introduction to DevSecOps +layout: custom +parent: Topic 1 - Introduction to SDLC and DevSecOps +has_children: false +has_toc: false +nav_order: 5 +--- + + +# Chapter 5 - Introduction to DevSecOps + +## Defining DevSecOps +- Dev = Development +- Sec = Security +- Ops = Operations + +**DevSecOps is a methodology that integrates security practices within the DevOps process.** The main goal of DevSecOps is to embed security in every part of the development lifecycle, from initial design through integration, testing, deployment, and software delivery. + +Ok, now what? You just have to start integrating this into your coding practices? Actually yes, the whole reason this curriculum is applicable for every person working in IT is because it is best development practice to have a secure lifecycle throughout all of the processes IT goes through when developing a project. + +
+ DevSecOps +

Source: Red Hat

+
+ + + + +## Why Implement DevSecOps: + +**The Importance of Security in SDLC:** + +The software development lifecycle (SDLC) is a framework used to develop, deploy, and maintain software. A common problem in software development is that security related activities are deferred until the testing phase, which is late in the SDLC after most of the critical design and implementation has been completed. Missing a security related risk could be costly, set back progress, and go unnoticed causing room for further severe impact. + +**What is "Shift" Testing:** + +"Shift left" and "shift right" are terms that emphasize implementing security practices throughout the SDLC. By adopting shift left and shift right principles, teams are able to fix security flaws early on. They are meant to evaluate and ensure quality of the project by focusing on continuous testing methods. + +To **shift left** is to incorporate security testing as soon as possible to find vulnerabilities and fix defects as early as possible in development. + +To **shift right** is to monitor user behavior, usage, performance, and security metrics in the production stage to verify software operability. + +

Source: Red Hat

+ + + + +## Tools and technologies: + +
Infrastructure as code scanning +

+ +

  • DevSecOps teams use open source tools like Terraform to manage and provision infrastructure like networks, virtual machines, and load balancers through code rather than doing it manually
  • + +
  • Terraform helps ensure that infrastructure is set up and updated consistently across hundreds or thousands of servers
  • + +
  • Infrastructure as a code scanning tools automatically check the infrastructure at the code level for noncompliance with security policies and standards
  • +

    Source: Microsoft

    +

    +
    + + + +
    Dynamic and Static Application Security Testing +

    + +

  • Dynamic application security testing: This process of testing tests the methods a bad actor might use to attack an application. This testing occurs while the application is running and is based on predefined use cases.
  • + +
  • Static application security testing: Before their code compiles, DevSecOps developers begin testing their custom code for security vulnerabilities. Static application security testing tools make this process easier with automatic checks and real-time feedback, often specifying exactly where an vulnerability is
  • + +
  • +

    Source: Microsoft

    +

    +
    + + +
    Container Scanning +

    + +

  • Container: A container is a standard unit of software that packages up code and all its dependencies so the application runs quickly and reliably from one computing environment to another
  • + +
  • Containers are widely used in DevSecOps because they help developers easily deploy self-contained units of code
  • + +
  • Container Image: Within a container is a container image, which is a executable software bundle that runs processes for the container. These images are often built using existing images or pulled from public repositories.
  • + +

    Source 1: Docker

    +

    Source 2: Microsoft

    +

    +
    + + + + +### References + +**1.** “What is DevSecOps?” *Red Hat*, [https://www.redhat.com/en/topics/devops/what-is-devsecops](https://www.redhat.com/en/topics/devops/what-is-devsecops). Accessed 8 Apr. 2024. + +**2.** “What is DevSecOps?” *Microsoft*, [https://www.microsoft.com/en-us/security/business/security-101/what-is-devsecops](https://www.microsoft.com/en-us/security/business/security-101/what-is-devsecops). Accessed 8 Apr. 2024. + +**3.** “Use containers to Build, Share and Run your applications” *Docker*, [https://www.docker.com/resources/what-container/](https://www.docker.com/resources/what-container/). Accessed 8 Apr. 2024. + +**4.** “Shift left vs. shift right” *Red Hat*, [https://www.redhat.com/en/topics/devops/shift-left-vs-shift-right](https://www.redhat.com/en/topics/devops/shift-left-vs-shift-right). Accessed 8 Apr. 2024. + diff --git a/docs/course/Topic-1-Software-Dev-and-DevSecOps/index.md b/docs/course/Topic-1-Software-Dev-and-DevSecOps/index.md new file mode 100644 index 0000000..2bbd54b --- /dev/null +++ b/docs/course/Topic-1-Software-Dev-and-DevSecOps/index.md @@ -0,0 +1,18 @@ +--- +title: Topic 1 - Introduction to SDLC and DevSecOps +layout: custom +parent: +has_children: true +has_toc: false +nav_order: 3 +--- + +# Topic 1 - Introduction to the SDLC and DevSecOps + +| Chapter | Learning Objectives | Lab Description | +|---------|---------------------|-----------------| +| Chapter 1: Introduction to SDLC | - Define Software Development Lifecycle
    - Understand the basics of SDLC methodologies
    - Explore the benefits of using different methodologies
    | | +| Chapter 2: Intro to Version Control | - Define version control
    - Understand the basics of version control systems
    - Explore the benefits of using version control
    - Introduction to common version control tools| | +| Chapter 3: Introduction to DevOps | - Define DevOps
    | +| Chapter 4: Introduction to CI/CD | - Establish effective documentation habits
    - Discuss the importance of READMEs and wikis
    - Explore best practices for inline code commenting | +| Chapter 4: Securing SDLC with DevSecOps | - Define DevSecOps
    | | \ No newline at end of file diff --git a/docs/course/Topic-1-Software-Dev-and-DevSecOps/review-and-knowledge-check/index.md b/docs/course/Topic-1-Software-Dev-and-DevSecOps/review-and-knowledge-check/index.md new file mode 100644 index 0000000..7ba6a92 --- /dev/null +++ b/docs/course/Topic-1-Software-Dev-and-DevSecOps/review-and-knowledge-check/index.md @@ -0,0 +1,9 @@ +--- +title: Topic Review and Knowledge Check +layout: custom +parent: Topic 1 - Introduction to SDLC and DevSecOps +has_toc: false +nav_order: 6 +--- + +# Topic Review and Knowledge Check \ No newline at end of file diff --git a/docs/course/topic-1-git/chapter-1-version-control/index.md b/docs/course/Topic-2-Git/chapter-1-version-control/index.md similarity index 97% rename from docs/course/topic-1-git/chapter-1-version-control/index.md rename to docs/course/Topic-2-Git/chapter-1-version-control/index.md index 97e85f6..2d5aa6e 100644 --- a/docs/course/topic-1-git/chapter-1-version-control/index.md +++ b/docs/course/Topic-2-Git/chapter-1-version-control/index.md @@ -1,7 +1,7 @@ --- -title: Chapter 1 - Introduction to Version Control +title: Chapter 1 - Version Control layout: custom -parent: Topic 1 - Git +parent: Topic 2 - Git has_children: false has_toc: false nav_order: 1 diff --git a/docs/course/topic-1-git/chapter-2-understanding-git/Git.jpg b/docs/course/Topic-2-Git/chapter-2-understanding-git/Git.jpg similarity index 100% rename from docs/course/topic-1-git/chapter-2-understanding-git/Git.jpg rename to docs/course/Topic-2-Git/chapter-2-understanding-git/Git.jpg diff --git a/docs/course/topic-1-git/chapter-2-understanding-git/index.md b/docs/course/Topic-2-Git/chapter-2-understanding-git/index.md similarity index 99% rename from docs/course/topic-1-git/chapter-2-understanding-git/index.md rename to docs/course/Topic-2-Git/chapter-2-understanding-git/index.md index bac5343..2410bc7 100644 --- a/docs/course/topic-1-git/chapter-2-understanding-git/index.md +++ b/docs/course/Topic-2-Git/chapter-2-understanding-git/index.md @@ -1,7 +1,7 @@ --- title: Chapter 2 - Git Fundamentals layout: custom -parent: Topic 1 - Git +parent: Topic 2 - Git has_toc: false has_children: false nav_order: 2 diff --git a/docs/course/topic-1-git/chapter-2-understanding-git/lab/csd-lab-1.md b/docs/course/Topic-2-Git/chapter-2-understanding-git/lab/csd-lab-1.md similarity index 100% rename from docs/course/topic-1-git/chapter-2-understanding-git/lab/csd-lab-1.md rename to docs/course/Topic-2-Git/chapter-2-understanding-git/lab/csd-lab-1.md diff --git a/docs/course/topic-1-git/chapter-3-Intermediate-Concepts/index.md b/docs/course/Topic-2-Git/chapter-3-Intermediate-Concepts/index.md similarity index 99% rename from docs/course/topic-1-git/chapter-3-Intermediate-Concepts/index.md rename to docs/course/Topic-2-Git/chapter-3-Intermediate-Concepts/index.md index 1929e27..dccd1bd 100644 --- a/docs/course/topic-1-git/chapter-3-Intermediate-Concepts/index.md +++ b/docs/course/Topic-2-Git/chapter-3-Intermediate-Concepts/index.md @@ -1,7 +1,7 @@ --- title: Chapter 3 - Git Intermediate Concepts layout: custom -parent: Topic 1 - Git +parent: Topic 2 - Git has_children: true has_toc: false nav_order: 3 diff --git a/docs/course/topic-1-git/chapter-3-Intermediate-Concepts/lab/git-lab-1.md b/docs/course/Topic-2-Git/chapter-3-Intermediate-Concepts/lab/git-lab-1.md similarity index 98% rename from docs/course/topic-1-git/chapter-3-Intermediate-Concepts/lab/git-lab-1.md rename to docs/course/Topic-2-Git/chapter-3-Intermediate-Concepts/lab/git-lab-1.md index b30f237..b20615c 100644 --- a/docs/course/topic-1-git/chapter-3-Intermediate-Concepts/lab/git-lab-1.md +++ b/docs/course/Topic-2-Git/chapter-3-Intermediate-Concepts/lab/git-lab-1.md @@ -1,7 +1,7 @@ --- layout: custom title: Lab 1. Version Control and Branching -grand_parent: Topic 1 - Git +grand_parent: Topic 2 - Git parent: Chapter 3 - Git Intermediate Concepts nav_order: 1 --- diff --git a/docs/course/topic-1-git/chapter-4-git-best-practices/index.md b/docs/course/Topic-2-Git/chapter-4-git-best-practices/index.md similarity index 99% rename from docs/course/topic-1-git/chapter-4-git-best-practices/index.md rename to docs/course/Topic-2-Git/chapter-4-git-best-practices/index.md index a505e2e..2001747 100644 --- a/docs/course/topic-1-git/chapter-4-git-best-practices/index.md +++ b/docs/course/Topic-2-Git/chapter-4-git-best-practices/index.md @@ -1,7 +1,7 @@ --- title: Chapter 4 - Git Best Practices layout: custom -parent: Topic 1 - Git +parent: Topic 2 - Git has_toc: false nav_order: 4 --- diff --git a/docs/course/Topic-2-Git/chapter-5-advanced-git-techniques/index.md b/docs/course/Topic-2-Git/chapter-5-advanced-git-techniques/index.md new file mode 100644 index 0000000..123b55f --- /dev/null +++ b/docs/course/Topic-2-Git/chapter-5-advanced-git-techniques/index.md @@ -0,0 +1,9 @@ +--- +title: Chapter 6 - Advanced Git Techniques +layout: custom +parent: Topic 2 - Git +has_toc: false +nav_order: 5 +--- + +# Chapter 6 - Advanced Git Techniques \ No newline at end of file diff --git a/docs/course/topic-1-git/index.md b/docs/course/Topic-2-Git/index.md similarity index 95% rename from docs/course/topic-1-git/index.md rename to docs/course/Topic-2-Git/index.md index f0867a1..51ac42e 100644 --- a/docs/course/topic-1-git/index.md +++ b/docs/course/Topic-2-Git/index.md @@ -1,12 +1,12 @@ --- -title: Topic 1 - Git +title: Topic 2 - Git layout: custom has_children: true has_toc: false -nav_order: 3 +nav_order: 4 --- -# Topic 1 - Git +# Topic 2 - Git | Chapter | Learning Objectives | Lab Description | |---------|---------------------|-----------------| diff --git a/docs/course/Topic-2-Git/review-and-knowledge-check/index.md b/docs/course/Topic-2-Git/review-and-knowledge-check/index.md new file mode 100644 index 0000000..69dd512 --- /dev/null +++ b/docs/course/Topic-2-Git/review-and-knowledge-check/index.md @@ -0,0 +1,9 @@ +--- +title: Topic Review and Knowledge Check +layout: custom +parent: Topic 2 - Git +has_toc: false +nav_order: 6 +--- + +# Topic Review and Knowledge Check \ No newline at end of file diff --git a/docs/course/topic-2-DevOps/chapter-2-intro-to-ci-cd/index.md b/docs/course/Topic-3-CICD-Concepts/chapter-1-cicd-core-concepts/index.md similarity index 98% rename from docs/course/topic-2-DevOps/chapter-2-intro-to-ci-cd/index.md rename to docs/course/Topic-3-CICD-Concepts/chapter-1-cicd-core-concepts/index.md index dd063e7..3dc7f71 100644 --- a/docs/course/topic-2-DevOps/chapter-2-intro-to-ci-cd/index.md +++ b/docs/course/Topic-3-CICD-Concepts/chapter-1-cicd-core-concepts/index.md @@ -1,13 +1,13 @@ --- -title: Chapter 2 - Intro to CI/CD +title: Chapter 1 - CI/CD Fundamentals layout: custom -parent: Topic 2 - DevOps +parent: Topic 3 - CI/CD Fundamentals has_children: false has_toc: false nav_order: 2 --- -# Introduction to CI/CD +# CI/CD Fundamentals

    CI/CD, short for Continuous Integration and Continuous Delivery, is a part of the DevOps process. “It is a collection of principles and practices designed to help development teams ensure the reliable delivery of frequent code changes.”

    diff --git a/docs/course/topic-2-DevOps/chapter-4-webhooks/index.md b/docs/course/Topic-3-CICD-Concepts/chapter-2-webhooks/index.md similarity index 97% rename from docs/course/topic-2-DevOps/chapter-4-webhooks/index.md rename to docs/course/Topic-3-CICD-Concepts/chapter-2-webhooks/index.md index 877ec53..32c0b09 100644 --- a/docs/course/topic-2-DevOps/chapter-4-webhooks/index.md +++ b/docs/course/Topic-3-CICD-Concepts/chapter-2-webhooks/index.md @@ -1,9 +1,9 @@ --- -title: Chapter 4 - Webhooks +title: Chapter 2 - Webhooks layout: custom -parent: Topic 2 - DevOps +parent: Topic 3 - CI/CD Fundamentals has_toc: false -nav_order: 4 +nav_order: 2 --- ## Utilizing Web Hooks for Continuous Integration diff --git a/docs/course/topic-2-DevOps/chapter-5-automation/index.md b/docs/course/Topic-3-CICD-Concepts/chapter-3-automated-testing/index.md similarity index 98% rename from docs/course/topic-2-DevOps/chapter-5-automation/index.md rename to docs/course/Topic-3-CICD-Concepts/chapter-3-automated-testing/index.md index 0979ccd..e22dc38 100644 --- a/docs/course/topic-2-DevOps/chapter-5-automation/index.md +++ b/docs/course/Topic-3-CICD-Concepts/chapter-3-automated-testing/index.md @@ -1,10 +1,10 @@ --- -title: Chapter 5 - Automated Tests +title: Chapter 2 - Automated Tests layout: custom -parent: Topic 2 - DevOps +parent: Topic 3 - CI/CD Fundamentals has_children: false has_toc: false -nav_order: 5 +nav_order: 3 --- # Automated Testing in CI/CD diff --git a/docs/course/topic-2-DevOps/chapter-6-deployment/index.md b/docs/course/Topic-3-CICD-Concepts/chapter-4-deployment/index.md similarity index 99% rename from docs/course/topic-2-DevOps/chapter-6-deployment/index.md rename to docs/course/Topic-3-CICD-Concepts/chapter-4-deployment/index.md index ce4878a..f0bb9f9 100644 --- a/docs/course/topic-2-DevOps/chapter-6-deployment/index.md +++ b/docs/course/Topic-3-CICD-Concepts/chapter-4-deployment/index.md @@ -1,10 +1,10 @@ --- -title: Chapter 6 - Deployment +title: Chapter 4 - Deployment layout: custom -parent: Topic 2 - DevOps +parent: Topic 3 - CI/CD Fundamentals has_toc: false has_children: true -nav_order: 6 +nav_order: 4 --- # Introduction to Deployment diff --git a/docs/course/topic-2-DevOps/chapter-6-deployment/lab/deployment-lab-1.md b/docs/course/Topic-3-CICD-Concepts/chapter-4-deployment/lab/deployment-lab-1.md similarity index 99% rename from docs/course/topic-2-DevOps/chapter-6-deployment/lab/deployment-lab-1.md rename to docs/course/Topic-3-CICD-Concepts/chapter-4-deployment/lab/deployment-lab-1.md index 5eda465..bacea92 100644 --- a/docs/course/topic-2-DevOps/chapter-6-deployment/lab/deployment-lab-1.md +++ b/docs/course/Topic-3-CICD-Concepts/chapter-4-deployment/lab/deployment-lab-1.md @@ -1,8 +1,8 @@ --- title: Lab 1. Configuring a Simple CI/CD Pipeline layout: custom -grand_parent: Topic 2 - DevOps -parent: Chapter 6 - Deployment +grand_parent: Topic 3 - CI/CD Fundamentals +parent: Chapter 4 - Deployment nav_order: 2 --- **Estimated Time to Complete:** 60 minutes diff --git a/docs/course/topic-2-DevOps/chapter-6-deployment/lab/imgs/jenkins-login.png b/docs/course/Topic-3-CICD-Concepts/chapter-4-deployment/lab/imgs/jenkins-login.png similarity index 100% rename from docs/course/topic-2-DevOps/chapter-6-deployment/lab/imgs/jenkins-login.png rename to docs/course/Topic-3-CICD-Concepts/chapter-4-deployment/lab/imgs/jenkins-login.png diff --git a/docs/course/topic-2-DevOps/chapter-3-containerization/lab/imgs/wireguard.png b/docs/course/Topic-3-CICD-Concepts/chapter-4-deployment/lab/imgs/wireguard.png similarity index 100% rename from docs/course/topic-2-DevOps/chapter-3-containerization/lab/imgs/wireguard.png rename to docs/course/Topic-3-CICD-Concepts/chapter-4-deployment/lab/imgs/wireguard.png diff --git a/docs/course/topic-2-DevOps/chapter-6-deployment/lab/overview.md b/docs/course/Topic-3-CICD-Concepts/chapter-4-deployment/lab/overview.md similarity index 96% rename from docs/course/topic-2-DevOps/chapter-6-deployment/lab/overview.md rename to docs/course/Topic-3-CICD-Concepts/chapter-4-deployment/lab/overview.md index d2fb8e6..65f011e 100644 --- a/docs/course/topic-2-DevOps/chapter-6-deployment/lab/overview.md +++ b/docs/course/Topic-3-CICD-Concepts/chapter-4-deployment/lab/overview.md @@ -1,8 +1,8 @@ --- title: Labs Overview layout: custom -grand_parent: Topic 2 - DevOps -parent: Chapter 6 - Deployment +grand_parent: Topic 3 - CI/CD Fundamentals +parent: Chapter 4 - Deployment nav_order: 1 --- diff --git a/docs/course/topic-2-DevOps/chapter-3-containerization/index.md b/docs/course/Topic-3-CICD-Concepts/chapter-5-containerization/index.md similarity index 99% rename from docs/course/topic-2-DevOps/chapter-3-containerization/index.md rename to docs/course/Topic-3-CICD-Concepts/chapter-5-containerization/index.md index ffcd8ee..7b56cf1 100644 --- a/docs/course/topic-2-DevOps/chapter-3-containerization/index.md +++ b/docs/course/Topic-3-CICD-Concepts/chapter-5-containerization/index.md @@ -1,10 +1,10 @@ --- -title: Chapter 3 - Containerization +title: Chapter 5 - Containerization layout: custom -parent: Topic 2 - DevOps +parent: Topic 3 - CI/CD Fundamentals has_children: true has_toc: false -nav_order: 3 +nav_order: 5 --- ## Definition of Containerization diff --git a/docs/course/topic-2-DevOps/chapter-3-containerization/lab/containerization-lab-1.md b/docs/course/Topic-3-CICD-Concepts/chapter-5-containerization/lab/containerization-lab-1.md similarity index 99% rename from docs/course/topic-2-DevOps/chapter-3-containerization/lab/containerization-lab-1.md rename to docs/course/Topic-3-CICD-Concepts/chapter-5-containerization/lab/containerization-lab-1.md index 1662012..d84c734 100644 --- a/docs/course/topic-2-DevOps/chapter-3-containerization/lab/containerization-lab-1.md +++ b/docs/course/Topic-3-CICD-Concepts/chapter-5-containerization/lab/containerization-lab-1.md @@ -1,8 +1,8 @@ --- layout: custom title: Lab 1. Containerizing a React Application -grand_parent: Topic 2 - DevOps -parent: Chapter 3 - Containerization +grand_parent: Topic 3 - CI/CD Fundamentals +parent: Chapter 5 - Containerization nav_order: 2 --- # Lab 1 - Containerizing a React Application diff --git a/docs/course/topic-2-DevOps/chapter-3-containerization/lab/containerization-lab-2.md b/docs/course/Topic-3-CICD-Concepts/chapter-5-containerization/lab/containerization-lab-2.md similarity index 98% rename from docs/course/topic-2-DevOps/chapter-3-containerization/lab/containerization-lab-2.md rename to docs/course/Topic-3-CICD-Concepts/chapter-5-containerization/lab/containerization-lab-2.md index cf059df..7771157 100644 --- a/docs/course/topic-2-DevOps/chapter-3-containerization/lab/containerization-lab-2.md +++ b/docs/course/Topic-3-CICD-Concepts/chapter-5-containerization/lab/containerization-lab-2.md @@ -1,8 +1,8 @@ --- layout: custom title: Lab 2. Accessing Corporate Network and AWS ECR -grand_parent: Topic 2 - DevOps -parent: Chapter 3 - Containerization +grand_parent: Topic 3 - CI/CD Fundamentals +parent: Chapter 5 - Containerization nav_order: 3 --- # Lab 2 - Accessing Corporate Network and AWS ECR diff --git a/docs/course/topic-2-DevOps/chapter-3-containerization/lab/imgs/clone.png b/docs/course/Topic-3-CICD-Concepts/chapter-5-containerization/lab/imgs/clone.png similarity index 100% rename from docs/course/topic-2-DevOps/chapter-3-containerization/lab/imgs/clone.png rename to docs/course/Topic-3-CICD-Concepts/chapter-5-containerization/lab/imgs/clone.png diff --git a/docs/course/topic-2-DevOps/chapter-3-containerization/lab/imgs/dashboard.png b/docs/course/Topic-3-CICD-Concepts/chapter-5-containerization/lab/imgs/dashboard.png similarity index 100% rename from docs/course/topic-2-DevOps/chapter-3-containerization/lab/imgs/dashboard.png rename to docs/course/Topic-3-CICD-Concepts/chapter-5-containerization/lab/imgs/dashboard.png diff --git a/docs/course/topic-2-DevOps/chapter-3-containerization/lab/imgs/fork.png b/docs/course/Topic-3-CICD-Concepts/chapter-5-containerization/lab/imgs/fork.png similarity index 100% rename from docs/course/topic-2-DevOps/chapter-3-containerization/lab/imgs/fork.png rename to docs/course/Topic-3-CICD-Concepts/chapter-5-containerization/lab/imgs/fork.png diff --git a/docs/course/topic-2-DevOps/chapter-6-deployment/lab/imgs/wireguard.png b/docs/course/Topic-3-CICD-Concepts/chapter-5-containerization/lab/imgs/wireguard.png similarity index 100% rename from docs/course/topic-2-DevOps/chapter-6-deployment/lab/imgs/wireguard.png rename to docs/course/Topic-3-CICD-Concepts/chapter-5-containerization/lab/imgs/wireguard.png diff --git a/docs/course/topic-2-DevOps/chapter-3-containerization/lab/overview.md b/docs/course/Topic-3-CICD-Concepts/chapter-5-containerization/lab/overview.md similarity index 96% rename from docs/course/topic-2-DevOps/chapter-3-containerization/lab/overview.md rename to docs/course/Topic-3-CICD-Concepts/chapter-5-containerization/lab/overview.md index 8598680..f0cb904 100644 --- a/docs/course/topic-2-DevOps/chapter-3-containerization/lab/overview.md +++ b/docs/course/Topic-3-CICD-Concepts/chapter-5-containerization/lab/overview.md @@ -1,8 +1,8 @@ --- title: Labs Overview layout: custom -grand_parent: Topic 2 - DevOps -parent: Chapter 3 - Containerization +grand_parent: Topic 3 - CI/CD Fundamentals +parent: Chapter 5 - Containerization nav_order: 1 --- diff --git a/docs/course/Topic-3-CICD-Concepts/index.md b/docs/course/Topic-3-CICD-Concepts/index.md new file mode 100644 index 0000000..07ffe84 --- /dev/null +++ b/docs/course/Topic-3-CICD-Concepts/index.md @@ -0,0 +1,13 @@ +--- +title: Topic 3 - CI/CD Fundamentals +layout: custom +has_children: true +has_toc: false +nav_order: 5 +--- + +# Topic 3 - CI/CD Fundamentals + +| Chapter | Learning Objectives | Lab Description | +|---------|---------------------|-----------------| + diff --git a/docs/course/Topic-3-CICD-Concepts/review-and-knowledge-check/index.md b/docs/course/Topic-3-CICD-Concepts/review-and-knowledge-check/index.md new file mode 100644 index 0000000..6801c83 --- /dev/null +++ b/docs/course/Topic-3-CICD-Concepts/review-and-knowledge-check/index.md @@ -0,0 +1,9 @@ +--- +title: Topic Review and Knowledge Check +layout: custom +parent: Topic 3 - CI/CD Fundamentals +has_toc: false +nav_order: 5 +--- + +# Topic Review and Knowledge Check \ No newline at end of file diff --git a/docs/course/topic-3-devsecops/chapter-1-devsecops/index.md b/docs/course/Topic-4-Devsecops-Fundmentals/chapter-1-devsecops/index.md similarity index 99% rename from docs/course/topic-3-devsecops/chapter-1-devsecops/index.md rename to docs/course/Topic-4-Devsecops-Fundmentals/chapter-1-devsecops/index.md index ccea82b..1499ad3 100644 --- a/docs/course/topic-3-devsecops/chapter-1-devsecops/index.md +++ b/docs/course/Topic-4-Devsecops-Fundmentals/chapter-1-devsecops/index.md @@ -1,7 +1,7 @@ --- title: Chapter 1 - DevSecOps layout: custom -parent: Topic 3 - DevSecOps +parent: Topic 4 - DevSecOps Fundamentals has_toc: false nav_order: 1 --- diff --git a/docs/course/topic-3-devsecops/chapter-1-devsecops/labs/devsecops-lab-1.md b/docs/course/Topic-4-Devsecops-Fundmentals/chapter-1-devsecops/labs/devsecops-lab-1.md similarity index 100% rename from docs/course/topic-3-devsecops/chapter-1-devsecops/labs/devsecops-lab-1.md rename to docs/course/Topic-4-Devsecops-Fundmentals/chapter-1-devsecops/labs/devsecops-lab-1.md diff --git a/docs/course/topic-3-devsecops/chapter-2-security-checks-in-CICD/index.md b/docs/course/Topic-4-Devsecops-Fundmentals/chapter-2-security-checks-in-CICD/index.md similarity index 99% rename from docs/course/topic-3-devsecops/chapter-2-security-checks-in-CICD/index.md rename to docs/course/Topic-4-Devsecops-Fundmentals/chapter-2-security-checks-in-CICD/index.md index cf2ce22..318e6ff 100644 --- a/docs/course/topic-3-devsecops/chapter-2-security-checks-in-CICD/index.md +++ b/docs/course/Topic-4-Devsecops-Fundmentals/chapter-2-security-checks-in-CICD/index.md @@ -1,7 +1,7 @@ --- title: Chapter 2 - Security Checks in CI/CD layout: custom -parent: Topic 3 - DevSecOps +parent: Topic 4 - DevSecOps Fundamentals has_children: true has_toc: false nav_order: 2 diff --git a/docs/course/topic-3-devsecops/chapter-2-security-checks-in-CICD/lab/devsecops-lab-1.md b/docs/course/Topic-4-Devsecops-Fundmentals/chapter-2-security-checks-in-CICD/lab/devsecops-lab-1.md similarity index 100% rename from docs/course/topic-3-devsecops/chapter-2-security-checks-in-CICD/lab/devsecops-lab-1.md rename to docs/course/Topic-4-Devsecops-Fundmentals/chapter-2-security-checks-in-CICD/lab/devsecops-lab-1.md diff --git a/docs/course/topic-3-devsecops/chapter-2-security-checks-in-CICD/lab/overview.md b/docs/course/Topic-4-Devsecops-Fundmentals/chapter-2-security-checks-in-CICD/lab/overview.md similarity index 100% rename from docs/course/topic-3-devsecops/chapter-2-security-checks-in-CICD/lab/overview.md rename to docs/course/Topic-4-Devsecops-Fundmentals/chapter-2-security-checks-in-CICD/lab/overview.md diff --git a/docs/course/topic-3-devsecops/index.md b/docs/course/Topic-4-Devsecops-Fundmentals/index.md similarity index 90% rename from docs/course/topic-3-devsecops/index.md rename to docs/course/Topic-4-Devsecops-Fundmentals/index.md index 91dad1d..db60ffc 100644 --- a/docs/course/topic-3-devsecops/index.md +++ b/docs/course/Topic-4-Devsecops-Fundmentals/index.md @@ -1,12 +1,12 @@ --- -title: Topic 3 - DevSecOps +title: Topic 4 - DevSecOps Fundamentals layout: custom has_children: true has_toc: false nav_order: 5 --- -# Topic 3 - DevSecOps +# Topic 4 - DevSecOps Fundamentals | Chapter | Learning Objectives | Lab Description | |---------|---------------------|-----------------| diff --git a/docs/course/Topic-5-Cloud/index.md b/docs/course/Topic-5-Cloud/index.md new file mode 100644 index 0000000..3e922b2 --- /dev/null +++ b/docs/course/Topic-5-Cloud/index.md @@ -0,0 +1,15 @@ +--- +title: Topic 5 - Cloud +layout: custom +has_children: true +has_toc: false +nav_order: 6 +--- + +# Topic 5 - Cloud + +| Chapter | Learning Objectives | Lab Description | +|---------|---------------------|-----------------| +| Chapter 1: Intro to Cloud | + + diff --git a/docs/course/topic-1-git/chapter-5-advanced-git-techniques/index.md b/docs/course/topic-1-git/chapter-5-advanced-git-techniques/index.md deleted file mode 100644 index e69de29..0000000 diff --git a/docs/course/topic-2-DevOps/index.md b/docs/course/topic-2-DevOps/index.md deleted file mode 100644 index f740141..0000000 --- a/docs/course/topic-2-DevOps/index.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Topic 2 - DevOps -layout: custom -has_children: true -has_toc: false -nav_order: 4 ---- - -# Topic 2 - Development & Operations (DevOps) - -| Chapter | Learning Objectives | Lab Description | -|---------|---------------------|-----------------| -| Chapter 1: Intro to DevOps | - Define DevOps and explore its challenges and benefits
    - Discuss roles in Development and Operations and the DevOps lifecycle | | -| Chapter 2: Intro to CI/CD | - Explain CI/CD within the DevOps framework
    - Discuss CI/CD lifecycle, benefits, and methods | | -| Chapter 3: Containerization | - Define containerization and its advantages in cloud computing
    - Explore Kubernetes and microservices architectures
    - Learn about container application consistency | **Lab 1: Containerizing a React Application**
    - Create and run a Docker image of a React application
    - Interact with a running Docker container
    **Lab 2: Accessing Corporate Network and AWS ECR**
    - Establish a VPN and use AWS IAM credentials to authenticate and push Docker images to AWS ECR | -| Chapter 4: Webhooks | - Discuss the role and setup of webhooks in CI/CD automation
    - Explore webhook triggers and their applications | | -| Chapter 5: Automated Tests | - Outline the role of automated testing in CI/CD
    - Discuss strategies and integration into the pipeline | | -| Chapter 6: Deployment | - Define deployment environments and strategies
    - Explore deployment challenges in large-scale environments | **Lab: Configuring a Simple Jenkins Pipeline**
    - Automate a Dockerized application deployment using Jenkins
    - Create and configure a Jenkins pipeline with webhooks | - diff --git a/docs/course/topic-3-devsecops/chapter-3-security-frameworks/index.md b/docs/course/topic-3-devsecops/chapter-3-security-frameworks/index.md deleted file mode 100644 index e69de29..0000000 diff --git a/docs/course/topic-3-devsecops/chapter-4-cloud-security/index.md b/docs/course/topic-3-devsecops/chapter-4-cloud-security/index.md deleted file mode 100644 index e69de29..0000000 diff --git a/docs/course/topic-3-devsecops/chapter-5-threat-modeling-and-risk-assessment/index.md b/docs/course/topic-3-devsecops/chapter-5-threat-modeling-and-risk-assessment/index.md deleted file mode 100644 index e69de29..0000000 diff --git a/docs/course/topic-3-devsecops/chapter-6-secure-code-and-hardening/index.md b/docs/course/topic-3-devsecops/chapter-6-secure-code-and-hardening/index.md deleted file mode 100644 index e69de29..0000000 diff --git a/docs/course/topic-3-devsecops/chapter-6-secure-code-and-hardening/labs/securing-a-vulnerable-web-app.md b/docs/course/topic-3-devsecops/chapter-6-secure-code-and-hardening/labs/securing-a-vulnerable-web-app.md deleted file mode 100644 index e69de29..0000000 diff --git a/docs/course/topic-3-devsecops/chapter-6-secure-code-and-hardening/labs/sql-injection-lab.md b/docs/course/topic-3-devsecops/chapter-6-secure-code-and-hardening/labs/sql-injection-lab.md deleted file mode 100644 index e69de29..0000000 diff --git a/docs/course/topic-3-devsecops/chapter-7-supply-chain-security/index.md b/docs/course/topic-3-devsecops/chapter-7-supply-chain-security/index.md deleted file mode 100644 index e69de29..0000000 diff --git a/docs/course/topic-3-devsecops/chapter-7-supply-chain-security/labs/detecting-vulnerabilities-lab.md b/docs/course/topic-3-devsecops/chapter-7-supply-chain-security/labs/detecting-vulnerabilities-lab.md deleted file mode 100644 index 66aef38..0000000 --- a/docs/course/topic-3-devsecops/chapter-7-supply-chain-security/labs/detecting-vulnerabilities-lab.md +++ /dev/null @@ -1 +0,0 @@ -detecting vulnerabilities in open source dependencies \ No newline at end of file diff --git a/docs/other/index.md b/docs/other/index.md index a4d252b..8f76555 100644 --- a/docs/other/index.md +++ b/docs/other/index.md @@ -3,5 +3,5 @@ title: Other Documents layout: custom has_children: true has_toc: false -nav_order: 6 +nav_order: 7 --- \ No newline at end of file diff --git a/index.md b/index.md index bbd553d..b42a6aa 100644 --- a/index.md +++ b/index.md @@ -4,9 +4,6 @@ layout: custom nav_order: 0 --- # DevSecOps Curriculum 💻 ->> Made by 2024 University of Washington Informatics Capstone Team Info Innovators - ->> Sponsored by Boeing Welcome to our open-source DevSecOps curriculum! @@ -37,10 +34,3 @@ To understand the skills gap that new graduates face, refer to our [User Researc ## Contributing to the Curriculum 🤝 Contributions are welcome! Help us keep the curriculum relevant and effective by updating content, adding new exercises, or providing feedback. - -### Connect with the Creators 🔗 -- [Sirena Akopyan](https://www.linkedin.com/in/sirena-akopyan/) -- [Bhavya Garlapati](https://www.linkedin.com/in/bhavya-garlapati-95ab46225/) -- [Eric Kim](https://www.linkedin.com/in/taehyunnkim/) -- [Mari Woodworth](https://www.linkedin.com/in/marikowoodworth/) -- [Brandon Mendoza](https://www.linkedin.com/in/bwmendo/) From c1ea00c99e7a0dcb9b199d38826796e07056e73d Mon Sep 17 00:00:00 2001 From: MorVered7 Date: Tue, 22 Apr 2025 09:35:20 -0700 Subject: [PATCH 04/17] added images --- .../chapter-1-Intro-to-Cloud/index.md | 102 ++++++++++++++++++ .../Topic-6-DevSecOps-in-Industry/index.md | 0 images/introtocloudcapstone.png | Bin 0 -> 72713 bytes 3 files changed, 102 insertions(+) create mode 100644 docs/course/Topic-5-Cloud/chapter-1-Intro-to-Cloud/index.md create mode 100644 docs/course/Topic-6-DevSecOps-in-Industry/index.md create mode 100644 images/introtocloudcapstone.png diff --git a/docs/course/Topic-5-Cloud/chapter-1-Intro-to-Cloud/index.md b/docs/course/Topic-5-Cloud/chapter-1-Intro-to-Cloud/index.md new file mode 100644 index 0000000..09d728b --- /dev/null +++ b/docs/course/Topic-5-Cloud/chapter-1-Intro-to-Cloud/index.md @@ -0,0 +1,102 @@ +# Introduction to Cloud + +The cloud has become the foundation upon which DevSecOps practices are built. From scalable infrastructure to rapid deployment capabilities, understanding the cloud is key to implementing secure, efficient pipelines. + +--- + +## What is Cloud Computing? + +Imagine needing a powerful computer to test your code, store large amounts of data, or run an app for millions of users. Instead of buying expensive hardware, you rent what you need—on demand, from someone else’s infrastructure. That, in essence, is cloud computing. + +Cloud computing provides on-demand access to computing resources—like servers, storage, and networking—delivered over the internet. Instead of managing physical hardware, teams can scale up or down their computing needs quickly and cost-effectively. + +> **NIST Definition**: "Cloud computing is a model for enabling ubiquitous, convenient, on-demand network access to a shared pool of configurable computing resources." + +--- + +## Key Benefits + +- **Scalability**: Adjust resources based on demand +- **Cost efficiency**: Pay only for what you use +- **Speed**: Rapid provisioning of infrastructure +- **Accessibility**: Work from anywhere + +--- + +## Example Scenario + +Ani is building a web app that lets users upload and edit videos. She needs a way to store large video files, process them quickly, and make the app available globally. Instead of setting up servers herself, Ani uses Amazon Web Services (AWS) to host her application, run processing jobs, and store videos in the cloud. The cloud lets her focus on building features—not managing hardware. + +--- + +## Cloud Service Models + +Cloud services fall into three main categories. Think of them as layers of abstraction that handle more and more of the infrastructure for you: + +### 1. IaaS – Infrastructure as a Service +You rent virtual machines, storage, and networking. You manage the OS and software. +**Examples**: AWS EC2, Microsoft Azure Virtual Machines + +### 2. PaaS – Platform as a Service +You build apps on top of a managed platform. The provider handles the OS, runtime, and infrastructure. +**Examples**: Heroku, Google App Engine + +### 3. SaaS – Software as a Service +You use the software over the internet without worrying about how it runs. +**Examples**: Google Workspace, GitHub + +--- + +## Cloud Deployment Models + +Different organizations use the cloud in different ways depending on their needs, size, and security posture. + +- **Public Cloud** + Services offered over the internet and shared across organizations. + *Examples*: AWS, Azure, GCP + *Use Case*: Startups, scalable applications + +- **Private Cloud** + Cloud environment dedicated to a single organization. + *Use Case*: Healthcare, financial institutions + +- **Hybrid Cloud** + Mix of public and private clouds. + *Use Case*: Enterprises with legacy systems + +- **Multi-Cloud** + Using services from multiple cloud providers. + *Use Case*: Large enterprises avoiding vendor lock-in + +--- + +## Cloud Security Fundamentals + +Security in the cloud is a shared responsibility between the cloud provider and the customer. + +### Shared Responsibility Model + +- **Provider**: Security *of* the cloud (hardware, infrastructure, etc.) +- **Customer**: Security *in* the cloud (data, apps, IAM) + +### Key Concepts + +- **IAM (Identity & Access Management)**: Control who can access what, and what actions they can take +- **Encryption**: Protect data in transit and at rest +- **Logging & Monitoring**: Track system activity for threats and auditing + +--- + +## Summary + +Cloud computing is the backbone of modern DevSecOps. It allows teams to innovate quickly, deploy securely, and scale easily. From choosing the right service model to understanding your security responsibilities, cloud knowledge is essential for any DevSecOps practitioner. + +--- + +## Resources + +- [Google Cloud Security Overview](https://cloud.google.com/blog/topics/developers-practitioners/google-cloud-security-overview) +- [AWS Shared Responsibility Model](https://aws.amazon.com/compliance/shared-responsibility-model/) +- [Azure Cloud Adoption Framework](https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/) +- [NIST SP 800-145](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-145.pdf) +- [IBM – What is Cloud Computing](https://www.ibm.com/think/topics/cloud-computing) diff --git a/docs/course/Topic-6-DevSecOps-in-Industry/index.md b/docs/course/Topic-6-DevSecOps-in-Industry/index.md new file mode 100644 index 0000000..e69de29 diff --git a/images/introtocloudcapstone.png b/images/introtocloudcapstone.png new file mode 100644 index 0000000000000000000000000000000000000000..b6bd764cf7709a78140dcf92ddb5f3d4499cfbcd GIT binary patch literal 72713 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�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 Qi~}v!(wTo*)B3Of29wExf&c&j literal 0 HcmV?d00001 From 0b78e6bf25f8a95fad8f9d16d25c0a959ef01bcd Mon Sep 17 00:00:00 2001 From: MorVered7 Date: Tue, 22 Apr 2025 09:40:57 -0700 Subject: [PATCH 05/17] added image to cloud lesson --- Gemfile.lock | 3 +++ docs/course/Topic-5-Cloud/chapter-1-Intro-to-Cloud/index.md | 3 +++ 2 files changed, 6 insertions(+) diff --git a/Gemfile.lock b/Gemfile.lock index 8a36229..f6e430e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -65,6 +65,8 @@ GEM safe_yaml (1.0.5) sass-embedded (1.69.5-arm64-darwin) google-protobuf (~> 3.23) + sass-embedded (1.69.5-x64-mingw-ucrt) + google-protobuf (~> 3.23) sass-embedded (1.69.5-x86_64-darwin) google-protobuf (~> 3.23) sass-embedded (1.69.5-x86_64-linux-gnu) @@ -76,6 +78,7 @@ GEM PLATFORMS arm64-darwin-23 + x64-mingw-ucrt x86_64-darwin-23 x86_64-linux diff --git a/docs/course/Topic-5-Cloud/chapter-1-Intro-to-Cloud/index.md b/docs/course/Topic-5-Cloud/chapter-1-Intro-to-Cloud/index.md index 09d728b..0247881 100644 --- a/docs/course/Topic-5-Cloud/chapter-1-Intro-to-Cloud/index.md +++ b/docs/course/Topic-5-Cloud/chapter-1-Intro-to-Cloud/index.md @@ -45,6 +45,9 @@ You build apps on top of a managed platform. The provider handles the OS, runtim You use the software over the internet without worrying about how it runs. **Examples**: Google Workspace, GitHub +![Cloud Service Models](../../../../images/introtocloudcapstone.png) + + --- ## Cloud Deployment Models From 831f2a382f7a1de4216d433bb591080b1611eb54 Mon Sep 17 00:00:00 2001 From: MorVered7 Date: Tue, 22 Apr 2025 09:44:41 -0700 Subject: [PATCH 06/17] updated industry --- docs/course/Topic-6-DevSecOps-in-Industry/index.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/course/Topic-6-DevSecOps-in-Industry/index.md b/docs/course/Topic-6-DevSecOps-in-Industry/index.md index e69de29..3f98b31 100644 --- a/docs/course/Topic-6-DevSecOps-in-Industry/index.md +++ b/docs/course/Topic-6-DevSecOps-in-Industry/index.md @@ -0,0 +1,7 @@ +--- +title: Topic 6 - Industry +layout: custom +has_children: true +has_toc: false +nav_order: 6 +--- \ No newline at end of file From f5f6c9ec5b4444bc74aa5a3c0ebacce112d23b5c Mon Sep 17 00:00:00 2001 From: MorVered7 Date: Tue, 22 Apr 2025 09:47:51 -0700 Subject: [PATCH 07/17] fixed nav order --- docs/course/Topic-6-DevSecOps-in-Industry/index.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/course/Topic-6-DevSecOps-in-Industry/index.md b/docs/course/Topic-6-DevSecOps-in-Industry/index.md index 3f98b31..e63ce07 100644 --- a/docs/course/Topic-6-DevSecOps-in-Industry/index.md +++ b/docs/course/Topic-6-DevSecOps-in-Industry/index.md @@ -1,7 +1,13 @@ --- -title: Topic 6 - Industry +title: Topic 6 - DevSecOps in Industry layout: custom has_children: true has_toc: false -nav_order: 6 ---- \ No newline at end of file +nav_order: 7 +--- +# Topic 5 - Cloud + +| Chapter | Learning Objectives | Lab Description | +|---------|---------------------|-----------------| +| Chapter 1: Use of DevSecOps in Industry | + From ee852418d0294b466861d0b382a1c42fc95215ef Mon Sep 17 00:00:00 2001 From: MorVered7 Date: Tue, 22 Apr 2025 09:50:23 -0700 Subject: [PATCH 08/17] added cloud lesson in correct order --- .../course/Topic-5-Cloud/chapter-1-Intro-to-Cloud/index.md | 7 +++++++ docs/course/Topic-6-DevSecOps-in-Industry/index.md | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/course/Topic-5-Cloud/chapter-1-Intro-to-Cloud/index.md b/docs/course/Topic-5-Cloud/chapter-1-Intro-to-Cloud/index.md index 0247881..3866906 100644 --- a/docs/course/Topic-5-Cloud/chapter-1-Intro-to-Cloud/index.md +++ b/docs/course/Topic-5-Cloud/chapter-1-Intro-to-Cloud/index.md @@ -1,3 +1,10 @@ +--- +title: Chapter 1 - Intro to Cloud +layout: custom +parent: Topic 5 - Cloud +has_toc: false +nav_order: 1 +--- # Introduction to Cloud The cloud has become the foundation upon which DevSecOps practices are built. From scalable infrastructure to rapid deployment capabilities, understanding the cloud is key to implementing secure, efficient pipelines. diff --git a/docs/course/Topic-6-DevSecOps-in-Industry/index.md b/docs/course/Topic-6-DevSecOps-in-Industry/index.md index e63ce07..a66435c 100644 --- a/docs/course/Topic-6-DevSecOps-in-Industry/index.md +++ b/docs/course/Topic-6-DevSecOps-in-Industry/index.md @@ -5,7 +5,7 @@ has_children: true has_toc: false nav_order: 7 --- -# Topic 5 - Cloud +# Topic 6 - DevSecOps in Industry | Chapter | Learning Objectives | Lab Description | |---------|---------------------|-----------------| From 0c5e013995d255340a371ae8ee65e2549b9d0548 Mon Sep 17 00:00:00 2001 From: MorVered7 Date: Tue, 22 Apr 2025 09:55:25 -0700 Subject: [PATCH 09/17] added a few new lessons --- .../Topic-5-Cloud/chapter-2-cloud-in-devsecops/index.md | 7 +++++++ .../chapter-1-use-of-devsecops-in-industry/index.md | 7 +++++++ docs/other/index.md | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 docs/course/Topic-5-Cloud/chapter-2-cloud-in-devsecops/index.md create mode 100644 docs/course/Topic-6-DevSecOps-in-Industry/chapter-1-use-of-devsecops-in-industry/index.md diff --git a/docs/course/Topic-5-Cloud/chapter-2-cloud-in-devsecops/index.md b/docs/course/Topic-5-Cloud/chapter-2-cloud-in-devsecops/index.md new file mode 100644 index 0000000..5aa9f42 --- /dev/null +++ b/docs/course/Topic-5-Cloud/chapter-2-cloud-in-devsecops/index.md @@ -0,0 +1,7 @@ +--- +title: Chapter 2 - Cloud in DevSecOps +layout: custom +parent: Topic 5 - Cloud +has_toc: false +nav_order: 2 +--- \ No newline at end of file diff --git a/docs/course/Topic-6-DevSecOps-in-Industry/chapter-1-use-of-devsecops-in-industry/index.md b/docs/course/Topic-6-DevSecOps-in-Industry/chapter-1-use-of-devsecops-in-industry/index.md new file mode 100644 index 0000000..9de3268 --- /dev/null +++ b/docs/course/Topic-6-DevSecOps-in-Industry/chapter-1-use-of-devsecops-in-industry/index.md @@ -0,0 +1,7 @@ +--- +title: Chapter 1 - Use of DevSecOps in Industry +layout: custom +parent: Topic 6 - DevSecOps in Industry +has_toc: false +nav_order: 1 +--- \ No newline at end of file diff --git a/docs/other/index.md b/docs/other/index.md index 8f76555..94d86af 100644 --- a/docs/other/index.md +++ b/docs/other/index.md @@ -3,5 +3,5 @@ title: Other Documents layout: custom has_children: true has_toc: false -nav_order: 7 +nav_order: 8 --- \ No newline at end of file From 86a58fa470f8b702479c18b8678c752e23224afe Mon Sep 17 00:00:00 2001 From: emilychoi Date: Tue, 22 Apr 2025 11:19:15 -0700 Subject: [PATCH 10/17] working quiz feature but on the old content architecture --- .DS_Store | Bin 0 -> 6148 bytes Gemfile | 5 ++ Gemfile.lock | 8 ++ _config.yml | 6 +- _data/quizzes/chapter1.yml | 44 +++++++++ _includes/head_custom.html | 1 + _includes/quiz.html | 29 ++++++ _layouts/custom.html | 9 ++ _sass/custom/custom.scss | 2 + _sass/custom/quiz.scss | 65 ++++++++++++++ assets/js/quiz-reset.js | 21 +++++ assets/js/quiz.js | 84 ++++++++++++++++++ .../chapter-1-version-control/index.md | 7 ++ 13 files changed, 280 insertions(+), 1 deletion(-) create mode 100644 .DS_Store create mode 100644 _data/quizzes/chapter1.yml create mode 100644 _includes/quiz.html create mode 100644 _sass/custom/quiz.scss create mode 100644 assets/js/quiz-reset.js create mode 100644 assets/js/quiz.js diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..dbba498b3185f51153f3c3170e9da0c4fdd26f54 GIT binary patch literal 6148 zcmeHKO>fgM7=GP#Yr2Be14z3dMdDhG7BoJ@rR!RuNx)%2Z~#=2ri^H5JT)z4sw(vi ze+7vve+2#uCwN}lo07C#*@XN`_TxCuwtCOsyV>#ZjJghAV~>j-{1H!mV+Rc0T|5MN80_Z0wtnN zs6z5-LVkhyt-!2;8KLz7#WaOxNNHXnZWR;`6fxR9!>Fd{p~(MI;PY5g@Y5CMueHnw zZ4UEeC>}rcBTK)j{>)hSxL;VFiz#!*NkTuykM4|8gIV`r*V`{n$4f0v{ByN zsyG#==DhVj$eB0sC)2d!k6-iE3n}B^yzB=rqv5Pyzi}Xwi614yu@Xe#5R^Bsq9l~F zj+`c8s!p51Mxui>h<;_MOK^{gZf<$j_J~ zLg34;;<~|e;Ae0#pO4-+iDkkbGQUDk;M+*8r?}`e@%qTRaxKrs{t+uTPx4Plt&*(H zQLBpA(C`pw>)QQ>7!czE53x23#{H zwQ{lwbb4uFo~%>5v=P{jtpnD9tLgxMA6z8Hw!x)F_31#SjsU(Riu%R#O zy#M$9e*Vvk?3H!EI`CgPAj(~@+rgB~-nue5-fLZ?cSsz}TWVAiWM(^71>TBxkW}EF Y%LQQD;8G)M5cWqv*<_`K>z>% literal 0 HcmV?d00001 diff --git a/Gemfile b/Gemfile index d5810e3..e82b3ad 100644 --- a/Gemfile +++ b/Gemfile @@ -5,3 +5,8 @@ gem "jekyll", "~> 4.3.3" # installed by `gem jekyll` gem "just-the-docs", "0.8.1" # pinned to the current release # gem "just-the-docs" # always download the latest release + +gem "csv" +gem "base64" +gem "logger" +gem "bigdecimal" \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index 8a36229..0455425 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,8 +3,11 @@ GEM specs: addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) + base64 (0.2.0) + bigdecimal (3.1.9) colorator (1.1.0) concurrent-ruby (1.2.2) + csv (3.3.3) em-websocket (0.5.3) eventmachine (>= 0.12.9) http_parser.rb (~> 0) @@ -52,6 +55,7 @@ GEM listen (3.8.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) + logger (1.7.0) mercenary (0.4.0) pathutil (0.16.2) forwardable-extended (~> 2.6) @@ -80,8 +84,12 @@ PLATFORMS x86_64-linux DEPENDENCIES + base64 + bigdecimal + csv jekyll (~> 4.3.3) just-the-docs (= 0.8.1) + logger BUNDLED WITH 2.3.26 diff --git a/_config.yml b/_config.yml index a66183b..d2cb8a3 100644 --- a/_config.yml +++ b/_config.yml @@ -24,4 +24,8 @@ callouts: color: blue lab: title: Access The Lab - color: purple \ No newline at end of file + color: purple + +sass: + sass_dir: _sass + style: compressed diff --git a/_data/quizzes/chapter1.yml b/_data/quizzes/chapter1.yml new file mode 100644 index 0000000..2740540 --- /dev/null +++ b/_data/quizzes/chapter1.yml @@ -0,0 +1,44 @@ +questions: + - prompt: "What is the primary purpose of version control in software development?" + options: + - "It prevents unauthorized users from editing a file." + - "It allows developers to track changes, collaborate, and revert to previous versions of files if necessary." + - "It automates the process of building software from source code." + - "It helps manage user authentication systems in a project." + correct_index: 1 + explanation: "Version control allows developers to track changes, collaborate, and revert to previous versions of files if necessary. This helps maintain a history of changes and prevents conflicts when working collaboratively." + + - prompt: "What is one of the key advantages of using version control in the scenario where Armine and Tigran are working on the same project?" + options: + - "Version control allows them to share the same file without needing to merge their changes." + - "It ensures that both of their changes are automatically merged, without requiring them to review the changes." + - "It enables them to track their changes independently and merge their updates later, preventing conflicts." + - "It prevents them from making any changes to each other's files." + correct_index: 2 + explanation: "Version control enables Armine and Tigran to track their changes independently and merge their updates later, preventing conflicts. This process is essential when multiple developers are working on the same codebase." + + - prompt: "True or False: Version control systems, like GitHub, prevent all types of conflicts between developers working on the same project by automatically merging all changes." + options: + - "True" + - "False" + correct_index: 1 + explanation: "False. Version control systems help manage changes and alert developers to conflicts, but they do not automatically merge all changes. Developers must manually resolve conflicts." + + - prompt: "Which of the following is NOT true about version control systems?" + options: + - "They allow developers to view the history of changes made to files and revert to any previous state." + - "They can automatically detect and resolve any conflicts between different versions of a file." + - "They facilitate collaboration by allowing multiple developers to work on different parts of a project without interfering with each other." + - "They store different versions of files, enabling developers to work on multiple features simultaneously." + correct_index: 1 + explanation: "Version control systems help detect conflicts, but they do not automatically resolve them. Developers must review and merge conflicting changes manually." + + - prompt: "Which of the following best describes how GitHub helps in the version control process?" + options: + - "GitHub is used exclusively for backing up files and does not include version control features." + - "GitHub only serves as a cloud-based storage system for completed software projects and does not support versioning." + - "GitHub is a platform for organizing and managing tasks related to software development but does not play a role in version control." + - "GitHub integrates with version control systems to store files and track changes, while also providing a user interface for collaboration and version history." + correct_index: 3 + explanation: "GitHub is a version control platform that integrates with Git to store files, track changes, and provide collaboration features like issue tracking, pull requests, and version history." + diff --git a/_includes/head_custom.html b/_includes/head_custom.html index 3a75c49..543ff78 100644 --- a/_includes/head_custom.html +++ b/_includes/head_custom.html @@ -1,5 +1,6 @@ + \ No newline at end of file diff --git a/_includes/quiz.html b/_includes/quiz.html new file mode 100644 index 0000000..552cccf --- /dev/null +++ b/_includes/quiz.html @@ -0,0 +1,29 @@ +

    🧠 Knowledge Check

    +

    Answer the questions below to test your knowledge!

    + +
    + {% for q in include.data.questions %} +
    +

    Q{{ forloop.index }}: {{ q.prompt }}

    + + {% for option in q.options %} + + {% endfor %} + + +
    + {% endfor %} + + + + + +
    + + + diff --git a/_layouts/custom.html b/_layouts/custom.html index 63d4e2d..37d9555 100644 --- a/_layouts/custom.html +++ b/_layouts/custom.html @@ -33,5 +33,14 @@ {% if site.mermaid %} {% include components/mermaid.html %} {% endif %} + + + + + + \ No newline at end of file diff --git a/_sass/custom/custom.scss b/_sass/custom/custom.scss index 1cfb8b6..a6e542d 100644 --- a/_sass/custom/custom.scss +++ b/_sass/custom/custom.scss @@ -6,6 +6,8 @@ $code-dot-size: 0.6rem; $code-dot-gap: 0.5rem; $dot-margin: 0; +@import "quiz"; + @mixin light-syntax { --language-border-color: #ececec; --highlight-bg-color: #f6f8fa; diff --git a/_sass/custom/quiz.scss b/_sass/custom/quiz.scss new file mode 100644 index 0000000..24f28dd --- /dev/null +++ b/_sass/custom/quiz.scss @@ -0,0 +1,65 @@ +.quiz-form { + margin-top: 2rem; + padding: 1rem; + border: 2px solid #ccc; + border-radius: 10px; + background-color: #ffffff; + + .quiz-question { + margin-bottom: 1.5rem; + p { + font-weight: 600; + margin-bottom: 0.5rem; + } + + label { + display: block; + margin: 1rem; + cursor: pointer; + + input[type="radio"] { + margin-right: 0.5rem; + } + } + + .quiz-feedback { + padding: 0.5rem; + margin-top: 0.5rem; + border-radius: 0.5rem; + font-weight: bold; + + &.correct { + background-color: #d4edda; + color: #155724; + border: 1px solid #c3e6cb; + } + + &.incorrect { + background-color: #f8d7da; + color: #721c24; + border: 1px solid #f5c6cb; + } + } + } + + button { + margin-top: 0.5rem; + padding: 0.6rem 1.2rem; + background-color: #007acc; + color: white; + border: none; + border-radius: 6px; + cursor: pointer; + + &:hover { + background-color: #005fa3; + } + + &:disabled { + background-color: #cccccc; + color: #666666; + cursor: not-allowed; + opacity: 0.7; + } + } +} \ No newline at end of file diff --git a/assets/js/quiz-reset.js b/assets/js/quiz-reset.js new file mode 100644 index 0000000..0161904 --- /dev/null +++ b/assets/js/quiz-reset.js @@ -0,0 +1,21 @@ +function resetQuiz(quizId) { + const form = document.querySelector(`.quiz-form[data-quiz-id="${quizId}"]`); + const header = document.querySelector("#quiz-title"); + header.scrollIntoView({ behavior: "smooth", block: "start" }); + + const questions = form.querySelectorAll('.quiz-question'); + + questions.forEach((questionDiv) => { + const selected = questionDiv.querySelector('input[type="radio"]:checked'); + if (selected) selected.checked = false; + + const feedback = questionDiv.querySelector('.quiz-feedback'); + feedback.innerHTML = ''; + feedback.style.display = 'none'; + feedback.classList.remove('correct', 'incorrect'); + }); + + // Enable Submit button and hide Try Again button + form.querySelector('.submit-btn').disabled = false; + form.querySelector('.try-again-btn').style.display = 'none'; +} diff --git a/assets/js/quiz.js b/assets/js/quiz.js new file mode 100644 index 0000000..3a34dfe --- /dev/null +++ b/assets/js/quiz.js @@ -0,0 +1,84 @@ +function submitQuiz(quizId) { + const form = document.querySelector(`.quiz-form[data-quiz-id="${quizId}"]`); + const header = document.querySelector("#quiz-title"); + header.scrollIntoView({ behavior: "smooth", block: "start" }); + + const questions = form.querySelectorAll('.quiz-question'); + let allCorrect = true; + let allAnswered = true; + + questions.forEach((questionDiv, index) => { + const selected = questionDiv.querySelector('input[type="radio"]:checked'); + const feedback = questionDiv.querySelector('.quiz-feedback'); + + feedback.classList.remove('correct', 'incorrect'); + feedback.style.display = "none"; + + const correctIndex = window.quizData[quizId].questions[index].correct_index; + const explanation = window.quizData[quizId].questions[index].explanation; + const link = window.quizData[quizId].questions[index].link; + + if (!selected) { + feedback.innerHTML = `

    Please select an answer.

    `; + allAnswered = false; + allCorrect = false; + } else if (parseInt(selected.value) === correctIndex) { + feedback.innerHTML = `

    Correct! ✅

    ${explanation} See more

    `; + feedback.classList.add("correct"); + } else { + feedback.innerHTML = `

    Incorrect ❌

    ${explanation} Review here

    `; + feedback.classList.add("incorrect"); + allCorrect = false; + } + + feedback.style.display = "block"; + }); + + // Disable the Submit button and show Try Again button + form.querySelector('.submit-btn').disabled = true; + form.querySelector('.try-again-btn').style.display = 'inline-block'; + + if (allAnswered && allCorrect) { + triggerConfetti(); + } +} + +function triggerConfetti () { + var count = 200; + var defaults = { + origin: { y: 0.7 } + }; + + setTimeout(() => { + function fire(particleRatio, opts) { + confetti({ + ...defaults, + ...opts, + particleCount: Math.floor(count * particleRatio) + }); + } + + fire(0.25, { + spread: 26, + startVelocity: 55, + }); + fire(0.2, { + spread: 60, + }); + fire(0.35, { + spread: 100, + decay: 0.91, + scalar: 0.8 + }); + fire(0.1, { + spread: 120, + startVelocity: 25, + decay: 0.92, + scalar: 1.2 + }); + fire(0.1, { + spread: 120, + startVelocity: 45, + }); + }, 650); +} diff --git a/docs/course/topic-1-git/chapter-1-version-control/index.md b/docs/course/topic-1-git/chapter-1-version-control/index.md index 97e85f6..53453b3 100644 --- a/docs/course/topic-1-git/chapter-1-version-control/index.md +++ b/docs/course/topic-1-git/chapter-1-version-control/index.md @@ -29,6 +29,13 @@ Version control is **a system that records changes to a file or set of files ove A common tool for version control is GitHub. GitHub allows you acts as a central hub for all of the different versions of your code, kind of how in google docs you can see the history of your changes. Though there are many different systems for version control, we will be learning using GitHubs features. The syntax and user interface of different products are different, but the core elements are the same. +--- + +{% include quiz.html + id="chapter1" + data=site.data.quizzes.chapter1 +%} + ### References
    Expand From 95194a4fcc25a99fa4a32b7ed96b86242724c759 Mon Sep 17 00:00:00 2001 From: emilychoi Date: Tue, 22 Apr 2025 15:13:48 -0700 Subject: [PATCH 11/17] add topic 2 chapter 1 and chapter 2 quizzes --- _data/quizzes/{ => topic2}/chapter1.yml | 0 _data/quizzes/topic2/chapter2.yml | 41 +++++++++++++++++++ _layouts/custom.html | 6 ++- assets/js/quiz.js | 5 +-- .../chapter-1-version-control/index.md | 7 +++- .../chapter-2-understanding-git/index.md | 8 ++++ 6 files changed, 61 insertions(+), 6 deletions(-) rename _data/quizzes/{ => topic2}/chapter1.yml (100%) create mode 100644 _data/quizzes/topic2/chapter2.yml diff --git a/_data/quizzes/chapter1.yml b/_data/quizzes/topic2/chapter1.yml similarity index 100% rename from _data/quizzes/chapter1.yml rename to _data/quizzes/topic2/chapter1.yml diff --git a/_data/quizzes/topic2/chapter2.yml b/_data/quizzes/topic2/chapter2.yml new file mode 100644 index 0000000..493a92e --- /dev/null +++ b/_data/quizzes/topic2/chapter2.yml @@ -0,0 +1,41 @@ +questions: + - prompt: "In Git, all changes in your working directory are committed to the repository when you run git commit, even if they haven't been added to the staging area." + options: + - "True" + - "False" + correct_index: 1 + explanation: "False — Only changes that have been added to the staging area using git add will be included in a commit. Unstaged changes in the working directory are not committed." + + - prompt: "What happens when you run the command git checkout <branch-name>?" + options: + - "It creates a new branch called <branch-name> but doesn't switch to it." + - "It deleted the <branch-name> branch from the respository." + - "It uploads your changes to the remote repository." + - "It switches your local branch to <branch-name> and updates the working directory with that branch's files." + correct_index: 3 + explanation: "git checkout <branch-name> switches to the specified branch and updates the working directory with that branch's contents." + + - prompt: "In Git, the term _________ refers to a snapshot of your project at a specific point in time, which is stored in the repository after running git commit." + options: + - "Working Directory" + - "Staging Area" + - "Commit" + - "Branch" + correct_index: 2 + explanation: "A commit in Git represents a snapshot of your project at a specific point in time." + + - prompt: "Which of the following statements is FALSE regarding Git branches?" + options: + - "A branch in Git does not copy files but simply creates a new pointer to them." + - "You can use branches to experiment with new features without affecting the main codebase." + - "Once a branch is created, it automatically merges into the main branch after a set period." + - "A branch isolates development work, enabling concurrent tasks without conflicts." + correct_index: 2 + explanation: "A branch does NOT automatically merge into the main branch; you have to do it manually using git merge." + + - prompt: "If you delete a branch using git branch -d <branch-name>, the branch is permanently deleted from both your local and remote repositories." + options: + - "True" + - "False" + correct_index: 1 + explanation: "git branch -d only deletes the LOCAL branch. To delete a branch from the remote, you would use git push origin --delete <branch-name>." diff --git a/_layouts/custom.html b/_layouts/custom.html index 37d9555..89b95cd 100644 --- a/_layouts/custom.html +++ b/_layouts/custom.html @@ -36,7 +36,11 @@ diff --git a/assets/js/quiz.js b/assets/js/quiz.js index 3a34dfe..d282bbb 100644 --- a/assets/js/quiz.js +++ b/assets/js/quiz.js @@ -16,17 +16,16 @@ function submitQuiz(quizId) { const correctIndex = window.quizData[quizId].questions[index].correct_index; const explanation = window.quizData[quizId].questions[index].explanation; - const link = window.quizData[quizId].questions[index].link; if (!selected) { feedback.innerHTML = `

    Please select an answer.

    `; allAnswered = false; allCorrect = false; } else if (parseInt(selected.value) === correctIndex) { - feedback.innerHTML = `

    Correct! ✅

    ${explanation} See more

    `; + feedback.innerHTML = `

    Correct! ✅

    ${explanation}`; feedback.classList.add("correct"); } else { - feedback.innerHTML = `

    Incorrect ❌

    ${explanation} Review here

    `; + feedback.innerHTML = `

    Incorrect ❌

    ${explanation}`; feedback.classList.add("incorrect"); allCorrect = false; } diff --git a/docs/course/Topic-2-Git/chapter-1-version-control/index.md b/docs/course/Topic-2-Git/chapter-1-version-control/index.md index 189c10b..cb9489c 100644 --- a/docs/course/Topic-2-Git/chapter-1-version-control/index.md +++ b/docs/course/Topic-2-Git/chapter-1-version-control/index.md @@ -5,6 +5,8 @@ parent: Topic 2 - Git has_children: false has_toc: false nav_order: 1 +topic: topic2 +chapter: chapter1 --- # Chapter 1 - Introduction to Version Control @@ -32,10 +34,11 @@ A common tool for version control is GitHub. GitHub allows you acts as a central --- {% include quiz.html - id="chapter1" - data=site.data.quizzes.chapter1 + id="topic2-chapter1" + data=site.data.quizzes.topic2.chapter1 %} + ### References

    Expand diff --git a/docs/course/Topic-2-Git/chapter-2-understanding-git/index.md b/docs/course/Topic-2-Git/chapter-2-understanding-git/index.md index 2410bc7..6dbbc81 100644 --- a/docs/course/Topic-2-Git/chapter-2-understanding-git/index.md +++ b/docs/course/Topic-2-Git/chapter-2-understanding-git/index.md @@ -5,6 +5,8 @@ parent: Topic 2 - Git has_toc: false has_children: false nav_order: 2 +topic: topic2 +chapter: chapter2 --- # Git Fundamentals @@ -78,6 +80,12 @@ Creating a branch in Git is a fast and simple operation because it doesn't copy By using branches, you can manage the development of new features, fixes, and updates in a structured and organized manner, allowing for a smoother and more controlled workflow. +--- + +{% include quiz.html + id="topic2-chapter2" + data=site.data.quizzes.topic2.chapter2 +%} ### References
    From dd15988b9f15a23632704344e9de683525e781f6 Mon Sep 17 00:00:00 2001 From: emilychoi Date: Tue, 22 Apr 2025 16:49:52 -0700 Subject: [PATCH 12/17] fix padding on feedback popup --- _sass/custom/quiz.scss | 4 ++++ assets/js/quiz.js | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/_sass/custom/quiz.scss b/_sass/custom/quiz.scss index 24f28dd..ff34418 100644 --- a/_sass/custom/quiz.scss +++ b/_sass/custom/quiz.scss @@ -39,6 +39,10 @@ color: #721c24; border: 1px solid #f5c6cb; } + + p#feedback-title { + margin-top: 0.5rem; + } } } diff --git a/assets/js/quiz.js b/assets/js/quiz.js index d282bbb..386780a 100644 --- a/assets/js/quiz.js +++ b/assets/js/quiz.js @@ -22,10 +22,10 @@ function submitQuiz(quizId) { allAnswered = false; allCorrect = false; } else if (parseInt(selected.value) === correctIndex) { - feedback.innerHTML = `

    Correct! ✅

    ${explanation}`; + feedback.innerHTML = `

    Correct! ✅

    ${explanation}`; feedback.classList.add("correct"); } else { - feedback.innerHTML = `

    Incorrect ❌

    ${explanation}`; + feedback.innerHTML = `

    Incorrect ❌

    ${explanation}`; feedback.classList.add("incorrect"); allCorrect = false; } From d6fe924fe01fbef5b131bd62779d638cdf7fc9c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cmiraxnairgit=20config=20--global=20user=2Eemail?= =?UTF-8?q?=20=E2=80=9Cmiranair004=40gmail=2Ecom?= <“miranair004@gmail.com> Date: Wed, 23 Apr 2025 01:08:24 -0700 Subject: [PATCH 13/17] font slider done --- Gemfile.lock | 2 ++ _layouts/custom.html | 49 ++++++++++++++++++++++++++++++++++++++++ _sass/custom/custom.scss | 40 ++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+) diff --git a/Gemfile.lock b/Gemfile.lock index 8a36229..fd71458 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -12,6 +12,7 @@ GEM ffi (1.16.3) forwardable-extended (2.6.0) google-protobuf (3.25.1) + google-protobuf (3.25.1-x86_64-darwin) http_parser.rb (0.8.0) i18n (1.14.1) concurrent-ruby (~> 1.0) @@ -76,6 +77,7 @@ GEM PLATFORMS arm64-darwin-23 + x86_64-darwin-22 x86_64-darwin-23 x86_64-linux diff --git a/_layouts/custom.html b/_layouts/custom.html index 63d4e2d..0e79cdc 100644 --- a/_layouts/custom.html +++ b/_layouts/custom.html @@ -19,6 +19,12 @@ {% include components/children_nav.html %} {% endif %} + +

    + + + +
    {% include components/footer.html %}
    @@ -33,5 +39,48 @@ {% if site.mermaid %} {% include components/mermaid.html %} {% endif %} + {% include footer_custom.html %} + + + \ No newline at end of file diff --git a/_sass/custom/custom.scss b/_sass/custom/custom.scss index 1cfb8b6..6cb8fc7 100644 --- a/_sass/custom/custom.scss +++ b/_sass/custom/custom.scss @@ -19,6 +19,46 @@ $dot-margin: 0; --clipboard-checked-color: #43c743; } +/* font size slider*/ +/* Font size slider */ +html { + font-size: 16px; /* default font-size */ +} + +body { + font-size: 1rem; /* will scale with html's font-size */ +} + +h1 { + font-size: 2rem; /* relative to html font-size */ +} + +p { + font-size: 1rem; /* relative to html font-size */ +} + +#font-size-controls { + margin-top: 2rem; + text-align: center; + + button { + font-size: 1rem; + margin: 0 0.5rem; + padding: 0.5rem 1rem; + border: none; + border-radius: 5px; + background-color: #eee; + cursor: pointer; + transition: background-color 0.3s ease; + + &:hover { + background-color: #ddd; + } + } +} + + + .highlighter-rouge { @include light-syntax; From 41286f8e8a9e8e9e843059cb272b4d32c0992786 Mon Sep 17 00:00:00 2001 From: Katie Shi Date: Thu, 24 Apr 2025 00:29:33 -0700 Subject: [PATCH 14/17] dark/light mode --- _includes/nav_footer_custom.html | 31 ++++++++++++++++++++++- _sass/custom/custom.scss | 43 -------------------------------- _sass/custom/dark.scss | 20 +++++++++++++++ _sass/custom/light.scss | 16 ++++++++++++ docs/course/index.md | 2 +- 5 files changed, 67 insertions(+), 45 deletions(-) create mode 100644 _sass/custom/dark.scss create mode 100644 _sass/custom/light.scss diff --git a/_includes/nav_footer_custom.html b/_includes/nav_footer_custom.html index c215dc8..1e8dcc9 100644 --- a/_includes/nav_footer_custom.html +++ b/_includes/nav_footer_custom.html @@ -1,3 +1,32 @@ \ No newline at end of file + + + \ No newline at end of file diff --git a/_sass/custom/custom.scss b/_sass/custom/custom.scss index c50d7b7..88d9a8c 100644 --- a/_sass/custom/custom.scss +++ b/_sass/custom/custom.scss @@ -6,8 +6,6 @@ $code-dot-size: 0.6rem; $code-dot-gap: 0.5rem; $dot-margin: 0; -@import "quiz"; - @mixin light-syntax { --language-border-color: #ececec; --highlight-bg-color: #f6f8fa; @@ -21,46 +19,6 @@ $dot-margin: 0; --clipboard-checked-color: #43c743; } -/* font size slider*/ -/* Font size slider */ -html { - font-size: 16px; /* default font-size */ -} - -body { - font-size: 1rem; /* will scale with html's font-size */ -} - -h1 { - font-size: 2rem; /* relative to html font-size */ -} - -p { - font-size: 1rem; /* relative to html font-size */ -} - -#font-size-controls { - margin-top: 2rem; - text-align: center; - - button { - font-size: 1rem; - margin: 0 0.5rem; - padding: 0.5rem 1rem; - border: none; - border-radius: 5px; - background-color: #eee; - cursor: pointer; - transition: background-color 0.3s ease; - - &:hover { - background-color: #ddd; - } - } -} - - - .highlighter-rouge { @include light-syntax; @@ -291,7 +249,6 @@ div.highlighter-rouge > button, div.listingblock > div.content > button, figure. padding-top: 64px; flex: 1; min-width: 300px; - background-color: #fbfbfb; border-left: 1px solid #eeebee; h2 { diff --git a/_sass/custom/dark.scss b/_sass/custom/dark.scss new file mode 100644 index 0000000..3ca510a --- /dev/null +++ b/_sass/custom/dark.scss @@ -0,0 +1,20 @@ +/* Dark Mode Colors */ +$color-scheme: dark; +$body-background-color: $grey-dk-300; +$body-heading-color: $grey-lt-000; +$body-text-color: $grey-lt-300; +$link-color: $blue-000; +$nav-child-link-color: $grey-dk-000; +$sidebar-color: $grey-dk-300; +$base-button-color: $grey-dk-250; +$btn-primary-color: $blue-200; +$code-background-color: #31343f; /* OneDarkJekyll default for syntax-one-dark-vivid */ +$code-linenumber-color: #dee2f7; /* OneDarkJekyll .nf for syntax-one-dark-vivid */ +$feedback-color: darken($sidebar-color, 3%); +$table-background-color: $grey-dk-250; +$search-background-color: $grey-dk-250; +$search-result-preview-color: $grey-dk-000; +$border-color: $grey-dk-200; + +/* Syntax highlighting for code */ +@import "./vendor/OneDarkJekyll/syntax"; /* This is the one-dark-vivid atom syntax theme */ diff --git a/_sass/custom/light.scss b/_sass/custom/light.scss new file mode 100644 index 0000000..a5f60c4 --- /dev/null +++ b/_sass/custom/light.scss @@ -0,0 +1,16 @@ +$color-scheme: light !default; +$body-background-color: $white !default; +$body-heading-color: $grey-dk-300 !default; +$body-text-color: $grey-dk-100 !default; +$link-color: $purple-000 !default; +$nav-child-link-color: $grey-dk-100 !default; +$sidebar-color: $grey-lt-000 !default; +$base-button-color: #f7f7f7 !default; +$btn-primary-color: $purple-100 !default; +$code-background-color: $grey-lt-000 !default; +$feedback-color: darken($sidebar-color, 3%) !default; +$table-background-color: $white !default; +$search-background-color: $white !default; +$search-result-preview-color: $grey-dk-000 !default; + +@import "./vendor/OneLightJekyll/syntax"; \ No newline at end of file diff --git a/docs/course/index.md b/docs/course/index.md index 85f5e33..9af2ebc 100644 --- a/docs/course/index.md +++ b/docs/course/index.md @@ -9,7 +9,7 @@ nav_order: 1 - + From 0979a8aa06be346cc9e86c4bf088ce5bdd3f4fa8 Mon Sep 17 00:00:00 2001 From: Katie Shi Date: Thu, 15 May 2025 03:12:42 -0700 Subject: [PATCH 15/17] changed to remote theme for testing --- _config.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index d2cb8a3..f22d3ef 100644 --- a/_config.yml +++ b/_config.yml @@ -1,6 +1,8 @@ title: open-devsecops description: 'From Classroom to Industry: Bridging the DevSecOps Knowledge Gap with Open, Practical Learning.' -theme: just-the-docs +remote_theme: pmarsceill/just-the-docs +plugins: + - jekyll-remote-theme logo: "/assets/images/opendevsecops-transparent.png" favicon_ico: "/assets/images/opendevsecops-favicon.ico" From 49735f980d0251ddb2e0f5394500402d2b986a75 Mon Sep 17 00:00:00 2001 From: Katie Shi Date: Fri, 16 May 2025 15:02:56 -0700 Subject: [PATCH 16/17] changed remote theme to just-the-docs/just-the-docs --- Gemfile.lock | 2 ++ _config.yml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 9583550..1cadd50 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -15,6 +15,7 @@ GEM ffi (1.16.3) forwardable-extended (2.6.0) google-protobuf (3.25.1) + google-protobuf (3.25.1-arm64-darwin) google-protobuf (3.25.1-x86_64-darwin) http_parser.rb (0.8.0) i18n (1.14.1) @@ -83,6 +84,7 @@ GEM PLATFORMS arm64-darwin-23 + arm64-darwin-24 x64-mingw-ucrt x86_64-darwin-22 x86_64-darwin-23 diff --git a/_config.yml b/_config.yml index f22d3ef..ddd636b 100644 --- a/_config.yml +++ b/_config.yml @@ -1,6 +1,6 @@ title: open-devsecops description: 'From Classroom to Industry: Bridging the DevSecOps Knowledge Gap with Open, Practical Learning.' -remote_theme: pmarsceill/just-the-docs +remote_theme: just-the-docs/just-the-docs plugins: - jekyll-remote-theme From 852ec29f6051afcc3f1e5e8c195bb9e801145d87 Mon Sep 17 00:00:00 2001 From: Katie Shi Date: Fri, 16 May 2025 15:14:59 -0700 Subject: [PATCH 17/17] changing back to original theme --- _config.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/_config.yml b/_config.yml index ddd636b..d2cb8a3 100644 --- a/_config.yml +++ b/_config.yml @@ -1,8 +1,6 @@ title: open-devsecops description: 'From Classroom to Industry: Bridging the DevSecOps Knowledge Gap with Open, Practical Learning.' -remote_theme: just-the-docs/just-the-docs -plugins: - - jekyll-remote-theme +theme: just-the-docs logo: "/assets/images/opendevsecops-transparent.png" favicon_ico: "/assets/images/opendevsecops-favicon.ico"
    Topic Chapter and Title Interactive Lab