eaglelandsonce's picture
Update index.html
ccc0bfe verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Azure Release Gates Jeopardy</title>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
background-color: #f0f0f0;
margin: 0;
}
h1 {
color: #0078D4;
}
#game-board {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-auto-rows: 100px;
gap: 2px;
margin: 20px 0;
background-color: #000;
border: 4px solid #000;
}
.category {
background-color: #005a9e;
color: #fff;
font-weight: bold;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
font-size: 18px;
border: 1px solid #000;
}
.card {
background-color: #0078D4;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
font-size: 16px;
font-weight: bold;
cursor: pointer;
border: 1px solid #000;
text-align: center;
transition: background-color 0.3s;
}
.card:hover {
background-color: #005a9e;
}
.card.disabled {
background-color: #cccccc;
cursor: default;
}
#question-display {
width: 80%;
text-align: center;
margin-bottom: 20px;
}
#score {
font-size: 24px;
font-weight: bold;
color: #0078D4;
}
.answer-container {
display: flex;
justify-content: center;
margin-top: 20px;
}
.answer-btn {
margin: 5px;
padding: 10px 15px;
font-size: 18px;
cursor: pointer;
text-align: center;
border: 2px solid #005a9e;
border-radius: 5px;
background-color: #0078D4;
color: #fff;
font-weight: bold;
transition: background-color 0.3s, color 0.3s;
}
.answer-btn:hover {
background-color: #005a9e;
color: #f0f0f0;
}
.answer-btn.disabled {
background-color: #cccccc;
color: #666;
cursor: not-allowed;
}
.feedback {
margin-top: 10px;
font-size: 18px;
font-weight: bold;
}
</style>
</head>
<body>
<h1>Azure Release Gates Jeopardy</h1>
<p>
<strong>Learn More:</strong>
<a
href="https://learn.microsoft.com/en-us/azure/devops/pipelines/release/approvals/gates?view=azure-devops"
target="_blank"
>Azure DevOps Approval Gates</a
>
</p>
<div id="game-board">
<!-- Categories -->
<div class="category">Release Gates</div>
<div class="category">Approvals</div>
<div class="category">Business Hours</div>
<div class="category">Azure Functions</div>
<div class="category">REST API Checks</div>
</div>
<div id="question-display"></div>
<div id="score">Score: 0</div>
<script>
const categories = [
"Release Gates",
"Approvals",
"Business Hours",
"Azure Functions",
"REST API Checks"
];
const questions = [
// Release Gates (index 0)
[
{
q: "What is the purpose of release gates?",
a: [
"To automate pipeline approvals",
"To ensure deployment criteria are met before proceeding",
"To replace manual intervention"
],
correct: 1
},
{
q: "Which deployment gate validates infrastructure health?",
a: ["Query Azure Monitor Alerts", "Invoke REST API", "Manual approval"],
correct: 0
},
{
q: "What happens if a deployment gate times out?",
a: [
"The deployment proceeds",
"The stage fails",
"It retries indefinitely"
],
correct: 1
}
],
// Approvals (index 1)
[
{
q: "What are pre-deployment approvals used for?",
a: [
"Validating deployment readiness",
"Post-deployment testing",
"Auto-scaling resources"
],
correct: 0
},
{
q: "What does deferred approval allow?",
a: [
"Multiple approvers",
"Approvals at a later time",
"Skipping approvals"
],
correct: 1
},
{
q: "Who can approve a stage if a group is designated?",
a: [
"All members",
"At least one group member",
"An external admin"
],
correct: 1
}
],
// Business Hours (index 2)
[
{
q: "What is the purpose of the business hours check?",
a: [
"To ensure deployments only occur in a specified time window",
"To automate REST API checks",
"To validate security settings"
],
correct: 0
},
{
q: "What happens if business hours end before stage execution starts?",
a: [
"The check passes",
"The stage execution is withdrawn",
"It retries the next day"
],
correct: 1
},
{
q: "What type of approval is combined with business hours?",
a: [
"Pre-deployment approvals",
"Post-deployment gates",
"Static checks"
],
correct: 0
}
],
// Azure Functions (index 3)
[
{
q: "What are Azure Functions used for in deployment gates?",
a: [
"Triggering custom checks",
"Handling manual approvals",
"Managing stage retries"
],
correct: 0
},
{
q: "Which mode is recommended for Azure Function checks?",
a: ["Asynchronous", "Synchronous", "Manual"],
correct: 0
},
{
q: "How does an Azure Function check communicate a decision?",
a: [
"By returning a JSON payload",
"By making a REST API call back to Azure DevOps",
"By triggering a new build"
],
correct: 1
}
],
// REST API Checks (index 4)
[
{
q: "What is a REST API check used for?",
a: [
"Integrating external services",
"Validating pipelines YAML",
"Executing Azure Functions"
],
correct: 0
},
{
q: "What happens if a REST API check times out?",
a: [
"The associated stage is skipped",
"The check retries indefinitely",
"The pipeline restarts"
],
correct: 0
},
{
q: "Which response is expected for REST API checks to pass?",
a: [
"Successful status code",
"Timed-out requests",
"Failure logs"
],
correct: 0
}
]
];
let score = 0;
let totalCards = 15; // 5 categories x 3 questions each
let answeredCards = 0;
const gameBoard = document.getElementById("game-board");
const questionDisplay = document.getElementById("question-display");
const scoreDisplay = document.getElementById("score");
function createBoard() {
for (let row = 0; row < 3; row++) {
for (let col = 0; col < 5; col++) {
const card = document.createElement("div");
card.className = "card";
card.textContent = `$${(row + 1) * 100}`;
card.onclick = () => showQuestion(col, row, card);
gameBoard.appendChild(card);
}
}
}
function showQuestion(category, difficulty, cardElement) {
if (cardElement.classList.contains("disabled")) return;
const question = questions[category][difficulty];
const answerHtml = question.a
.map(
(answer, index) =>
`<button class="answer-btn" onclick="checkAnswer(${category}, ${difficulty}, ${index})">${answer}</button>`
)
.join("");
questionDisplay.innerHTML = `
<h2>${categories[category]} for $${(difficulty + 1) * 100}</h2>
<p>${question.q}</p>
<div class="answer-container">${answerHtml}</div>
`;
cardElement.classList.add("disabled");
cardElement.style.backgroundColor = "#cccccc";
answeredCards++;
}
function checkAnswer(category, difficulty, selectedAnswer) {
const question = questions[category][difficulty];
const correctAnswer = question.a[question.correct];
const isCorrect = selectedAnswer === question.correct;
const value = (difficulty + 1) * 100;
document.querySelectorAll(".answer-btn").forEach((btn) => {
btn.disabled = true;
btn.classList.add("disabled");
});
if (isCorrect) {
score += value;
questionDisplay.innerHTML += `<p class="feedback" style="color: green;">Correct! You earned $${value}.</p>`;
} else {
score -= value;
questionDisplay.innerHTML += `<p class="feedback" style="color: red;">Wrong! You lost $${value}. The correct answer was: ${correctAnswer}</p>`;
}
scoreDisplay.textContent = `Score: ${score}`;
if (answeredCards === totalCards) {
endGame();
}
}
function endGame() {
questionDisplay.innerHTML = `<h2>Game Over!</h2><p>Your final score is $${score}.</p>`;
}
createBoard();
</script>
</body>
</html>