Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop (fork) Branch Update #8

Merged
merged 1 commit into from
Oct 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion .github/workflows/wiki.yml
Original file line number Diff line number Diff line change
@@ -1,20 +1,45 @@
name: Deploy to Wiki
on:
pull_request:
paths:
- 'wiki/**'
push:
branches:
- develop
paths:
- 'wiki/**'
# Triggers this workflow when the wiki is changed
# Triggers this workflow when the wiki is changed.
# (see https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#gollum).
gollum:

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
cancel-in-progress: true

jobs:
table_of_contents_check:
# To verify that the wiki's table of contents matches the headers accurately.
name: Check Wiki Table of Contents
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2

- name: Set up Bazel
uses: abhinavsingh/setup-bazel@v3
with:
version: 6.5.0

- name: Check Wiki Table of Contents
id: checkWikiToc
run: |
bazel run //scripts:wiki_table_of_contents_check -- ${GITHUB_WORKSPACE}

wiki-deploy:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04]
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/develop' }}
steps:
- uses: actions/checkout@v3
with:
Expand Down
9 changes: 9 additions & 0 deletions scripts/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,15 @@ kt_jvm_binary(
],
)

kt_jvm_binary(
name = "wiki_table_of_contents_check",
testonly = True,
main_class = "org.oppia.android.scripts.wiki.WikiTableOfContentsCheckKt",
runtime_deps = [
"//scripts/src/java/org/oppia/android/scripts/wiki:wiki_table_of_contents_check_lib",
],
)

kt_jvm_binary(
name = "run_coverage",
testonly = True,
Expand Down
18 changes: 18 additions & 0 deletions scripts/src/java/org/oppia/android/scripts/wiki/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"""
Libraries corresponding to scripting tools that help with continuous integration workflows.
"""

load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_library")

kt_jvm_library(
name = "wiki_table_of_contents_check_lib",
testonly = True,
srcs = [
"WikiTableOfContentsCheck.kt",
],
visibility = ["//scripts:oppia_script_binary_visibility"],
deps = [
"//scripts/src/java/org/oppia/android/scripts/common:bazel_client",
"//scripts/src/java/org/oppia/android/scripts/common:git_client",
],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package org.oppia.android.scripts.wiki

import java.io.File

/**
* Script for ensuring that the table of contents in each wiki page matches with its respective headers.
*
* Usage:
* bazel run //scripts:wiki_table_of_contents_check -- <path_to_default_working_directory>
*
* Arguments:
* - path_to_default_working_directory: The default working directory on the runner for steps, and the default location of repository.
*
* Example:
* bazel run //scripts:wiki_table_of_contents_check -- $(pwd)
*/
fun main(vararg args: String) {
// Path to the repo's wiki.
val wikiDirPath = "${args[0]}/wiki/"
val wikiDir = File(wikiDirPath)

// Check if the wiki directory exists.
if (wikiDir.exists() && wikiDir.isDirectory) {
processWikiDirectory(wikiDir)
println("WIKI TABLE OF CONTENTS CHECK PASSED")
} else {
println("No contents found in the Wiki directory.")
}
}

private fun processWikiDirectory(wikiDir: File) {
wikiDir.listFiles()?.forEach { file ->
checkTableOfContents(file)
}
}

private fun checkTableOfContents(file: File) {
val fileContents = file.readLines()
val tocStartIdx = fileContents.indexOfFirst {
it.contains(Regex("""##\s+Table\s+of\s+Contents""", RegexOption.IGNORE_CASE))
}
if (tocStartIdx == -1) {
return
}

// Skipping the blank line after the ## Table of Contents
val tocEndIdx = fileContents.subList(tocStartIdx + 2, fileContents.size).indexOfFirst {
it.startsWith("#")
}.takeIf { it != -1 }
?: error("Wiki doesn't contain headers referenced in Table of Contents.")

val tocSpecificLines = fileContents.subList(tocStartIdx, tocStartIdx + tocEndIdx + 1)

for (line in tocSpecificLines) {
if (line.trimStart().startsWith("- [") && !line.contains("https://")) {
validateTableOfContents(file, line)
}
}
}

private fun validateTableOfContents(file: File, line: String) {
val titleRegex = "\\[(.*?)\\]".toRegex()
val title = titleRegex.find(line)?.groupValues?.get(1)?.replace('-', ' ')
?.replace(Regex("[?&./:’'*!,(){}\\[\\]+]"), "")
?.trim()

val linkRegex = "\\(#(.*?)\\)".toRegex()
val link = linkRegex.find(line)?.groupValues?.get(1)?.removePrefix("#")?.replace('-', ' ')
?.replace(Regex("[?&./:’'*!,(){}\\[\\]+]"), "")
?.trim()

// Checks if the table of content title matches with the header link text.
val matches = title.equals(link, ignoreCase = true)
if (!matches) {
error(
"\nWIKI TABLE OF CONTENTS CHECK FAILED" +
"\nMismatch of Table of Content with headers in the File: ${file.name}. " +
"\nThe Title: '${titleRegex.find(line)?.groupValues?.get(1)}' " +
"doesn't match with its corresponding Link: '${linkRegex.find(line)?.groupValues?.get(1)}'."
)
}
}
16 changes: 16 additions & 0 deletions scripts/src/javatests/org/oppia/android/scripts/wiki/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""
Tests corresponding to wiki-related checks.
"""

load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_test")

kt_jvm_test(
name = "WikiTableOfContentsCheckTest",
srcs = ["WikiTableOfContentsCheckTest.kt"],
deps = [
"//scripts/src/java/org/oppia/android/scripts/wiki:wiki_table_of_contents_check_lib",
"//testing:assertion_helpers",
"//third_party:com_google_truth_truth",
"//third_party:org_jetbrains_kotlin_kotlin-test-junit",
],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
package org.oppia.android.scripts.wiki

import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
import org.oppia.android.testing.assertThrows
import java.io.ByteArrayOutputStream
import java.io.PrintStream

/** Tests for [WikiTableOfContentsCheck]. */
class WikiTableOfContentsCheckTest {
private val outContent: ByteArrayOutputStream = ByteArrayOutputStream()
private val originalOut: PrintStream = System.out
private val WIKI_TOC_CHECK_PASSED_OUTPUT_INDICATOR = "WIKI TABLE OF CONTENTS CHECK PASSED"
private val WIKI_TOC_CHECK_FAILED_OUTPUT_INDICATOR = "WIKI TABLE OF CONTENTS CHECK FAILED"

@field:[Rule JvmField] val tempFolder = TemporaryFolder()

@Before
fun setUp() {
System.setOut(PrintStream(outContent))
}

@After
fun tearDown() {
System.setOut(originalOut)
}

@Test
fun testWikiTOCCheck_noWikiDirExists_printsNoContentFound() {
runScript()
assertThat(outContent.toString().trim()).isEqualTo("No contents found in the Wiki directory.")
}

@Test
fun testWikiTOCCheck_noWikiDirectory_printsNoContentFound() {
tempFolder.newFile("wiki")
runScript()
assertThat(outContent.toString().trim()).isEqualTo("No contents found in the Wiki directory.")
}

@Test
fun testWikiTOCCheck_validWikiTOC_checkPass() {
tempFolder.newFolder("wiki")
val file = tempFolder.newFile("wiki/wiki.md")
file.writeText(
"""
## Table of Contents

- [Introduction](#introduction)
- [Usage](#usage)

## Introduction
Content

## Usage
Content
""".trimIndent()
)

runScript()

assertThat(outContent.toString().trim()).contains(WIKI_TOC_CHECK_PASSED_OUTPUT_INDICATOR)
}

@Test
fun testWikiTOCCheck_missingWikiTOC_returnsNoTOCFound() {
tempFolder.newFolder("wiki")
val file = tempFolder.newFile("wiki/wiki.md")
file.writeText(
"""
- [Introduction](#introduction)
- [Usage](#usage)

## Introduction
Content

## Usage
Content
""".trimIndent()
)

runScript()

assertThat(outContent.toString().trim()).contains(WIKI_TOC_CHECK_PASSED_OUTPUT_INDICATOR)
}

@Test
fun testWikiTOCCheck_wikiTOCReference_noHeadersFound_throwsException() {
tempFolder.newFolder("wiki")
val file = tempFolder.newFile("wiki/wiki.md")
file.writeText(
"""
## Table of Contents

- [Introduction](#introductions)

""".trimIndent()
)

val exception = assertThrows<IllegalStateException>() {
runScript()
}

assertThat(exception).hasMessageThat().contains(
"Wiki doesn't contain headers referenced in Table of Contents."
)
}

@Test
fun testWikiTOCCheck_mismatchWikiTOC_checkFail() {
tempFolder.newFolder("wiki")
val file = tempFolder.newFile("wiki/wiki.md")
file.writeText(
"""
## Table of Contents

- [Introduction](#introductions)
- [Usage](#usage)

## Introduction
Content

## Usage
Content
""".trimIndent()
)

val exception = assertThrows<IllegalStateException>() {
runScript()
}

assertThat(exception).hasMessageThat().contains(WIKI_TOC_CHECK_FAILED_OUTPUT_INDICATOR)
}

@Test
fun testWikiTOCCheck_validWikiTOCWithSeparator_checkPass() {
tempFolder.newFolder("wiki")
val file = tempFolder.newFile("wiki/wiki.md")
file.writeText(
"""
## Table of Contents

- [Introduction To Wiki](#introduction-to-wiki)
- [Usage Wiki-Content](#usage-wiki-content)

## Introduction
Content

## Usage
Content
""".trimIndent()
)

runScript()

assertThat(outContent.toString().trim()).contains(WIKI_TOC_CHECK_PASSED_OUTPUT_INDICATOR)
}

@Test
fun testWikiTOCCheck_validWikiTOCWithSpecialCharacter_checkPass() {
tempFolder.newFolder("wiki")
val file = tempFolder.newFile("wiki/wiki.md")
file.writeText(
"""
## Table of Contents

- [Introduction](#introduction?)
- [Usage?](#usage)

## Introduction
Content

## Usage
Content
""".trimIndent()
)

runScript()

assertThat(outContent.toString().trim()).contains(WIKI_TOC_CHECK_PASSED_OUTPUT_INDICATOR)
}

private fun runScript() {
main(tempFolder.root.absolutePath)
}
}
2 changes: 1 addition & 1 deletion wiki/Guidance-on-submitting-a-PR.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Note: If your change involves more than around 500 lines of code, we recommend f
- [Tips for getting your PR submitted](#tips-for-getting-your-pr-submitted)
- [Appendix: Resolving merge conflicts using the terminal](#appendix-resolving-merge-conflicts-using-the-terminal)
- [Appendix: Resolving merge conflicts using Android Studio](#appendix-resolving-merge-conflicts-using-android-studio)
- [Step 4: Tidy up and celebrate!](#step-4-tidy-up-and-celebrate-confetti_ball)
- [Step 4: Tidy up and celebrate! :confetti_ball:](#step-4-tidy-up-and-celebrate-confetti_ball)

## Step 1: Making a local code change

Expand Down
2 changes: 1 addition & 1 deletion wiki/Installing-Oppia-Android.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ This wiki page explains how to install Oppia Android on your local machine. If y
- [Prepare developer environment](#prepare-developer-environment)
- [Install oppia-android](#install-oppia-android)
- [Run the app from Android Studio](#run-the-app-from-android-studio)
- [Run the tests](#set-up-and-run-tests)
- [Set up and Run tests](#set-up-and-run-tests)
- [Step-by-Step guidance for setting up and running app modules robolectric test](#step-by-step-guidance-for-setting-up-and-running-app-modules-robolectric-test)
- [For tests that are in non-app modules, such as **domain** or **utility**:](#for-tests-that-are-in-non-app-modules-such-as-domain-or-utility)

Expand Down
2 changes: 1 addition & 1 deletion wiki/Interpreting-CI-Results.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Table of Contents

- [How to find the error message for a Failing CI check](#how-to-find-error-message-for-failing-ci-checks)
- [How to find error message for Failing CI checks](#how-to-find-error-message-for-failing-ci-checks)
- [Developer Video - Understanding CI check failures](#developer-video---understanding-ci-check-failures)

## How to find error message for Failing CI checks
Expand Down
Loading
Loading