Memory hook: An artifact should carry its identity and evidence from build to deployment.
Must remember
- Azure Pipelines and GitHub Actions use different YAML schemas. Triggers, conditions, jobs, stages and dependencies determine execution. Distinguish compile/template-time expressions from runtime variables in Azure Pipelines; quoting a value does not necessarily make a secret safe.
- In Azure Pipelines,
${{ }}expressions expand during template/plan construction and can use parameters;$[ ]expressions evaluate at runtime in their supported contexts;$(name)macro syntax resolves task variable values. A value first created by a running step cannot retroactively change an already-expanded template. Check expression phase and available context when a condition or variable is unexpectedly empty. - Hosted agents simplify maintenance; self-hosted agents need patching, tools, licences, network access and isolation. Never run untrusted code on a privileged persistent runner that holds production credentials. Parallelism reduces time only when dependencies, capacity and cost allow it.
- Reuse templates/actions with version pinning and review. Variable groups centralise configuration; environment checks/approvals gate deployments. Service connections authorise target operations; a pipeline's existence does not grant access to every subscription.
- Azure Artifacts/GitHub Packages provide package feeds. Upstream sources, views and permissions affect provenance and promotion. SemVer communicates compatibility; CalVer communicates release time. Lock dependencies and record immutable package/artifact versions.
- Unit tests isolate logic; integration tests validate real contracts; end-to-end tests check useful outcomes; load tests assess capacity. Coverage measures execution, not assertion quality. Publish results and fail on meaningful quality/security gates rather than merely collecting reports.
- Monitor duration, failures, flaky tests, queue delay, cache effectiveness and cost. Retain artifacts long enough for rollback/audit, with lifecycle policies for unused outputs. Migrate classic pipelines to YAML by preserving triggers, credentials, approvals and retention semantics, not only copying task names.
Choose under exam pressure
| Requirement | Choice and reason |
|---|---|
| Need reliable repeatable dependency installation | Pinned versions/lockfiles and trusted package feeds. |
| Only production needs manual approval | An environment approval/check at the deployment boundary. |
| Pipeline is slow but workers are idle | Inspect dependency ordering and queue/serial bottlenecks. |
Traps
- Code coverage does not prove behaviour is correct.
- An unpinned reusable action can change without your source changing.
- A cache is an optimisation, not a trusted release artifact.
Active recall
1. What should remain the same between staging and production?
The reviewed immutable application artifact; environment configuration can differ deliberately.
2. Why isolate self-hosted runners?
Jobs can affect persistent files, credentials and network access.
3. What does a package-feed view help organise?
Controlled exposure/promotion of package versions to intended consumers.
4. Why monitor flaky tests?
They undermine confidence and can conceal real regressions or waste retries.
5. What should a pipeline approval identify?
The exact artifact, change scope and validation evidence.